<!DOCTYPE html>
<html lang="zh-CN">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>SSM复习-cnblog | 凌歆的博客</title>
    <meta name="generator" content="VuePress 1.9.5">
    <link rel="icon" href="/img/favicon.ico">
    <meta name="description" content="web前端技术博客,专注web前端学习与总结。JavaScript,js,ES6,TypeScript,vue,React,python,css3,html5,Node,git,github等技术文章。">
    <meta name="keywords" content="前端博客,个人技术博客,前端,前端开发,前端框架,web前端,前端面试题,技术文档,学习,面试,JavaScript,js,ES6,TypeScript,vue,python,css3,html5,Node,git,github,markdown">
    <meta name="baidu-site-verification" content="7F55weZDDc">
    <meta name="theme-color" content="#11a8cd">
    
    <link rel="preload" href="/assets/css/0.styles.d9c8cf8c.css" as="style"><link rel="preload" href="/assets/js/app.57550e13.js" as="script"><link rel="preload" href="/assets/js/2.f014c35f.js" as="script"><link rel="preload" href="/assets/js/94.b6bc4a44.js" as="script"><link rel="prefetch" href="/assets/js/10.03a98811.js"><link rel="prefetch" href="/assets/js/100.145e708e.js"><link rel="prefetch" href="/assets/js/101.098ca5c8.js"><link rel="prefetch" href="/assets/js/102.4d45c69a.js"><link rel="prefetch" href="/assets/js/103.499de505.js"><link rel="prefetch" href="/assets/js/104.c2c1b9b6.js"><link rel="prefetch" href="/assets/js/105.4e9b0663.js"><link rel="prefetch" href="/assets/js/106.9bb8cf6f.js"><link rel="prefetch" href="/assets/js/107.a81b32d7.js"><link rel="prefetch" href="/assets/js/108.81511e67.js"><link rel="prefetch" href="/assets/js/109.6a6741bf.js"><link rel="prefetch" href="/assets/js/11.e8729182.js"><link rel="prefetch" href="/assets/js/110.de657fe7.js"><link rel="prefetch" href="/assets/js/111.b092af6d.js"><link rel="prefetch" href="/assets/js/112.2dca5709.js"><link rel="prefetch" href="/assets/js/113.dbed1fac.js"><link rel="prefetch" href="/assets/js/114.e95a0131.js"><link rel="prefetch" href="/assets/js/115.2e3e8285.js"><link rel="prefetch" href="/assets/js/116.e64f7fec.js"><link rel="prefetch" href="/assets/js/117.583552c9.js"><link rel="prefetch" href="/assets/js/118.aa5d18f0.js"><link rel="prefetch" href="/assets/js/119.0c7b52d7.js"><link rel="prefetch" href="/assets/js/12.d63acec2.js"><link rel="prefetch" href="/assets/js/120.13f86281.js"><link rel="prefetch" href="/assets/js/121.e2b5b7f9.js"><link rel="prefetch" href="/assets/js/122.5252216a.js"><link rel="prefetch" href="/assets/js/123.8b8a3503.js"><link rel="prefetch" href="/assets/js/124.60df855c.js"><link rel="prefetch" href="/assets/js/125.f073ab1c.js"><link rel="prefetch" href="/assets/js/126.7b73de6a.js"><link rel="prefetch" href="/assets/js/127.4e25971c.js"><link rel="prefetch" href="/assets/js/128.0edf0e06.js"><link rel="prefetch" href="/assets/js/129.5cb5a70a.js"><link rel="prefetch" href="/assets/js/13.2259ef71.js"><link rel="prefetch" href="/assets/js/130.00247fda.js"><link rel="prefetch" href="/assets/js/131.d6fc003a.js"><link rel="prefetch" href="/assets/js/132.1a32b18f.js"><link rel="prefetch" href="/assets/js/133.e46c0193.js"><link rel="prefetch" href="/assets/js/134.a6ad681f.js"><link rel="prefetch" href="/assets/js/135.2fcbe137.js"><link rel="prefetch" href="/assets/js/136.f69bf451.js"><link rel="prefetch" href="/assets/js/137.b9ef2fcc.js"><link rel="prefetch" href="/assets/js/138.7fdd9feb.js"><link rel="prefetch" href="/assets/js/139.a3a37c91.js"><link rel="prefetch" href="/assets/js/14.0d6b23b9.js"><link rel="prefetch" href="/assets/js/140.a7c013ae.js"><link rel="prefetch" href="/assets/js/141.956c36ce.js"><link rel="prefetch" href="/assets/js/142.5aacfe42.js"><link rel="prefetch" href="/assets/js/143.57d691ef.js"><link rel="prefetch" href="/assets/js/144.b1e5766e.js"><link rel="prefetch" href="/assets/js/145.463284b7.js"><link rel="prefetch" href="/assets/js/146.6cc6420c.js"><link rel="prefetch" href="/assets/js/147.5b78c5a2.js"><link rel="prefetch" href="/assets/js/148.8d1d7679.js"><link rel="prefetch" href="/assets/js/149.4e0eb213.js"><link rel="prefetch" href="/assets/js/15.f6fde69d.js"><link rel="prefetch" href="/assets/js/150.b183de37.js"><link rel="prefetch" href="/assets/js/151.729ae770.js"><link rel="prefetch" href="/assets/js/152.b1297018.js"><link rel="prefetch" href="/assets/js/153.bb991bca.js"><link rel="prefetch" href="/assets/js/154.6f2286aa.js"><link rel="prefetch" href="/assets/js/155.6a9c7e4d.js"><link rel="prefetch" href="/assets/js/156.f7bd535d.js"><link rel="prefetch" href="/assets/js/157.64c0065c.js"><link rel="prefetch" href="/assets/js/158.d31ae949.js"><link rel="prefetch" href="/assets/js/159.7daea8a7.js"><link rel="prefetch" href="/assets/js/16.7be21beb.js"><link rel="prefetch" href="/assets/js/160.33cc971a.js"><link rel="prefetch" href="/assets/js/161.1676442a.js"><link rel="prefetch" href="/assets/js/162.71378046.js"><link rel="prefetch" href="/assets/js/163.99e49959.js"><link rel="prefetch" href="/assets/js/164.306f07d2.js"><link rel="prefetch" href="/assets/js/165.170977c7.js"><link rel="prefetch" href="/assets/js/166.f8602525.js"><link rel="prefetch" href="/assets/js/167.eea5c001.js"><link rel="prefetch" href="/assets/js/168.0146a311.js"><link rel="prefetch" href="/assets/js/169.05f9c9d9.js"><link rel="prefetch" href="/assets/js/17.2543f471.js"><link rel="prefetch" href="/assets/js/170.25d602b2.js"><link rel="prefetch" href="/assets/js/171.1ada26a6.js"><link rel="prefetch" href="/assets/js/172.2a0f697c.js"><link rel="prefetch" href="/assets/js/173.230d8ca8.js"><link rel="prefetch" href="/assets/js/174.e3758a2b.js"><link rel="prefetch" href="/assets/js/175.0f19f8ea.js"><link rel="prefetch" href="/assets/js/176.bf70d37d.js"><link rel="prefetch" href="/assets/js/177.4400f272.js"><link rel="prefetch" href="/assets/js/178.85af7b89.js"><link rel="prefetch" href="/assets/js/179.4cfaaaa2.js"><link rel="prefetch" href="/assets/js/18.394415f8.js"><link rel="prefetch" href="/assets/js/180.449c8409.js"><link rel="prefetch" href="/assets/js/181.73276924.js"><link rel="prefetch" href="/assets/js/182.5fab25cc.js"><link rel="prefetch" href="/assets/js/183.ecd4934d.js"><link rel="prefetch" href="/assets/js/184.246092cf.js"><link rel="prefetch" href="/assets/js/185.c671cd86.js"><link rel="prefetch" href="/assets/js/186.49bd1963.js"><link rel="prefetch" href="/assets/js/187.1fb32764.js"><link rel="prefetch" href="/assets/js/188.7c6885e9.js"><link rel="prefetch" href="/assets/js/189.a8701dec.js"><link rel="prefetch" href="/assets/js/19.ca7db8ea.js"><link rel="prefetch" href="/assets/js/190.ae3d3bde.js"><link rel="prefetch" href="/assets/js/191.ad7cd44e.js"><link rel="prefetch" href="/assets/js/192.bc443842.js"><link rel="prefetch" href="/assets/js/193.e4755764.js"><link rel="prefetch" href="/assets/js/194.814112ce.js"><link rel="prefetch" href="/assets/js/195.1c0aaa80.js"><link rel="prefetch" href="/assets/js/196.a6bd7add.js"><link rel="prefetch" href="/assets/js/20.4e91cd31.js"><link rel="prefetch" href="/assets/js/21.f095e6e1.js"><link rel="prefetch" href="/assets/js/22.72f4b8ab.js"><link rel="prefetch" href="/assets/js/23.e94eb9d2.js"><link rel="prefetch" href="/assets/js/24.0eae7d6f.js"><link rel="prefetch" href="/assets/js/25.36157609.js"><link rel="prefetch" href="/assets/js/26.dc5b6cba.js"><link rel="prefetch" href="/assets/js/27.c19b7b63.js"><link rel="prefetch" href="/assets/js/28.3aceae59.js"><link rel="prefetch" href="/assets/js/29.536091b3.js"><link rel="prefetch" href="/assets/js/3.d11119c4.js"><link rel="prefetch" href="/assets/js/30.821a4a30.js"><link rel="prefetch" href="/assets/js/31.5238784c.js"><link rel="prefetch" href="/assets/js/32.10bc7179.js"><link rel="prefetch" href="/assets/js/33.c1ed69c9.js"><link rel="prefetch" href="/assets/js/34.8d384231.js"><link rel="prefetch" href="/assets/js/35.d8890e52.js"><link rel="prefetch" href="/assets/js/36.eca37ad5.js"><link rel="prefetch" href="/assets/js/37.802549e3.js"><link rel="prefetch" href="/assets/js/38.53841770.js"><link rel="prefetch" href="/assets/js/39.7ae44409.js"><link rel="prefetch" href="/assets/js/4.493b9bca.js"><link rel="prefetch" href="/assets/js/40.ce56364a.js"><link rel="prefetch" href="/assets/js/41.85f0114b.js"><link rel="prefetch" href="/assets/js/42.714da6e2.js"><link rel="prefetch" href="/assets/js/43.fee4437c.js"><link rel="prefetch" href="/assets/js/44.b039b68b.js"><link rel="prefetch" href="/assets/js/45.96a55605.js"><link rel="prefetch" href="/assets/js/46.956ffb03.js"><link rel="prefetch" href="/assets/js/47.147d9218.js"><link rel="prefetch" href="/assets/js/48.ff787b40.js"><link rel="prefetch" href="/assets/js/49.871eee87.js"><link rel="prefetch" href="/assets/js/5.e0ba07d7.js"><link rel="prefetch" href="/assets/js/50.99b7c29e.js"><link rel="prefetch" href="/assets/js/51.8ecbf4ba.js"><link rel="prefetch" href="/assets/js/52.53d91d7e.js"><link rel="prefetch" href="/assets/js/53.af8a0d2a.js"><link rel="prefetch" href="/assets/js/54.a2f848b5.js"><link rel="prefetch" href="/assets/js/55.267e9947.js"><link rel="prefetch" href="/assets/js/56.0b201c40.js"><link rel="prefetch" href="/assets/js/57.cbdfd6f7.js"><link rel="prefetch" href="/assets/js/58.636c0c3f.js"><link rel="prefetch" href="/assets/js/59.fc9216c4.js"><link rel="prefetch" href="/assets/js/6.b98373f2.js"><link rel="prefetch" href="/assets/js/60.34f16fc4.js"><link rel="prefetch" href="/assets/js/61.4d130bd8.js"><link rel="prefetch" href="/assets/js/62.927caa10.js"><link rel="prefetch" href="/assets/js/63.a451fee0.js"><link rel="prefetch" href="/assets/js/64.32a5d47b.js"><link rel="prefetch" href="/assets/js/65.bc099429.js"><link rel="prefetch" href="/assets/js/66.3953050d.js"><link rel="prefetch" href="/assets/js/67.e934823b.js"><link rel="prefetch" href="/assets/js/68.4bcb52b0.js"><link rel="prefetch" href="/assets/js/69.bede18c8.js"><link rel="prefetch" href="/assets/js/7.8de8df2d.js"><link rel="prefetch" href="/assets/js/70.fce1daac.js"><link rel="prefetch" href="/assets/js/71.ea0a8c5d.js"><link rel="prefetch" href="/assets/js/72.15382c9e.js"><link rel="prefetch" href="/assets/js/73.848364d3.js"><link rel="prefetch" href="/assets/js/74.5fd08a50.js"><link rel="prefetch" href="/assets/js/75.c937c70d.js"><link rel="prefetch" href="/assets/js/76.a0dacd5a.js"><link rel="prefetch" href="/assets/js/77.4019cc23.js"><link rel="prefetch" href="/assets/js/78.9676a9e1.js"><link rel="prefetch" href="/assets/js/79.e46e10d5.js"><link rel="prefetch" href="/assets/js/8.2098eb96.js"><link rel="prefetch" href="/assets/js/80.987e83cb.js"><link rel="prefetch" href="/assets/js/81.eb98ff36.js"><link rel="prefetch" href="/assets/js/82.623561a7.js"><link rel="prefetch" href="/assets/js/83.e256d909.js"><link rel="prefetch" href="/assets/js/84.7d06a550.js"><link rel="prefetch" href="/assets/js/85.b8d9879e.js"><link rel="prefetch" href="/assets/js/86.31c4581b.js"><link rel="prefetch" href="/assets/js/87.e06ee05e.js"><link rel="prefetch" href="/assets/js/88.81ef718d.js"><link rel="prefetch" href="/assets/js/89.ba237d2f.js"><link rel="prefetch" href="/assets/js/9.36092fd0.js"><link rel="prefetch" href="/assets/js/90.ad2c9d92.js"><link rel="prefetch" href="/assets/js/91.a661f52d.js"><link rel="prefetch" href="/assets/js/92.1c28035b.js"><link rel="prefetch" href="/assets/js/93.c8b8e3d6.js"><link rel="prefetch" href="/assets/js/95.92cea882.js"><link rel="prefetch" href="/assets/js/96.5373491b.js"><link rel="prefetch" href="/assets/js/97.bb39efc8.js"><link rel="prefetch" href="/assets/js/98.af7a030f.js"><link rel="prefetch" href="/assets/js/99.07dc87d8.js">
    <link rel="stylesheet" href="/assets/css/0.styles.d9c8cf8c.css">
  </head>
  <body class="theme-mode-light">
    <div id="app" data-server-rendered="true"><div class="theme-container sidebar-open have-rightmenu"><header class="navbar blur"><div title="目录" class="sidebar-button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" role="img" viewBox="0 0 448 512" class="icon"><path fill="currentColor" d="M436 124H12c-6.627 0-12-5.373-12-12V80c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12z"></path></svg></div> <a href="/" class="home-link router-link-active"><img src="https://lingxin-tanhua.oss-cn-shanghai.aliyuncs.com/QQ%E6%88%AA%E5%9B%BE20220503092755.png" alt="凌歆的博客" class="logo"> <span class="site-name can-hide">凌歆的博客</span></a> <div class="links"><div class="search-box"><input aria-label="Search" autocomplete="off" spellcheck="false" value=""> <!----></div> <nav class="nav-links can-hide"><div class="nav-item"><a href="/" class="nav-link">首页</a></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="前端" class="dropdown-title"><a href="/web/" class="link-title">前端</a> <span class="title" style="display:none;">前端</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><h4>学习笔记</h4> <ul class="dropdown-subitem-wrapper"><li class="dropdown-subitem"><a href="/note/html/" class="nav-link">HTML笔记</a></li><li class="dropdown-subitem"><a href="/note/js-low/" class="nav-link">JavaScript基础笔记</a></li><li class="dropdown-subitem"><a href="/note/js-high/" class="nav-link">JavaScript高阶笔记</a></li><li class="dropdown-subitem"><a href="/note/js-dom-bom/" class="nav-link">JavaScript DOM和BOM笔记</a></li><li class="dropdown-subitem"><a href="/note/jquery/" class="nav-link">jQuery笔记</a></li><li class="dropdown-subitem"><a href="/note/ajax/" class="nav-link">Ajax笔记</a></li><li class="dropdown-subitem"><a href="/note/nodejs/" class="nav-link">NodeJs笔记</a></li><li class="dropdown-subitem"><a href="/note/reg/" class="nav-link">正则表达式笔记</a></li><li class="dropdown-subitem"><a href="/note/vue/" class="nav-link">Vue笔记</a></li><li class="dropdown-subitem"><a href="/note/react/" class="nav-link">react笔记</a></li><li class="dropdown-subitem"><a href="/note/wx/" class="nav-link">微信小程序笔记</a></li><li class="dropdown-subitem"><a href="/note/uniapp/" class="nav-link">uniapp笔记</a></li><li class="dropdown-subitem"><a href="/note/echarts/" class="nav-link">echarts笔记</a></li><li class="dropdown-subitem"><a href="/note/git/" class="nav-link">Git笔记</a></li></ul></li></ul></div></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="后端" class="dropdown-title"><a href="/back/" class="link-title">后端</a> <span class="title" style="display:none;">后端</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/note/java/" class="nav-link">JAVA</a></li><li class="dropdown-item"><!----> <a href="/note/javaweb/" class="nav-link">JavaWeb</a></li><li class="dropdown-item"><!----> <a href="/note/mysql/" class="nav-link">MySql</a></li><li class="dropdown-item"><!----> <a href="/note/ssm/" class="nav-link">ssm</a></li></ul></div></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="算法" class="dropdown-title"><a href="/algor/" class="link-title">算法</a> <span class="title" style="display:none;">算法</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/note/sf/" class="nav-link">算法训练营</a></li><li class="dropdown-item"><!----> <a href="/note/js-sf/" class="nav-link">js数据结构与算法</a></li></ul></div></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="面试" class="dropdown-title"><a href="/mianshi/" class="link-title">面试</a> <span class="title" style="display:none;">面试</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/note/lqb/" class="nav-link">蓝桥杯备战</a></li><li class="dropdown-item"><!----> <a href="/note/ms/" class="nav-link">前端面试</a></li><li class="dropdown-item"><!----> <a href="/note/hmms/" class="nav-link">黑马面试</a></li><li class="dropdown-item"><!----> <a href="/note/xzms/" class="nav-link">校招零距离面试</a></li></ul></div></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="解决方案" class="dropdown-title"><a href="/resolve/" class="link-title">解决方案</a> <span class="title" style="display:none;">解决方案</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/note/qd-resolve/" class="nav-link">前端解决方案</a></li><li class="dropdown-item"><!----> <a href="/note/hd-resolve/" class="nav-link">后端解决方案</a></li></ul></div></div><div class="nav-item"><a href="/pages/beb6c0bd8a66cea6/" class="nav-link">收藏</a></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="索引" class="dropdown-title"><a href="/archives/" class="link-title">索引</a> <span class="title" style="display:none;">索引</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/categories/" class="nav-link">分类</a></li><li class="dropdown-item"><!----> <a href="/tags/" class="nav-link">标签</a></li><li class="dropdown-item"><!----> <a href="/archives/" class="nav-link">归档</a></li></ul></div></div> <a href="https://github.com/linxin1123/vuepress-blog" target="_blank" rel="noopener noreferrer" class="repo-link">
    GitHub
    <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></nav></div></header> <div class="sidebar-mask"></div> <div class="sidebar-hover-trigger"></div> <aside class="sidebar" style="display:none;"><div class="blogger"><img src="https://lingxin-tanhua.oss-cn-shanghai.aliyuncs.com/QQ%E6%88%AA%E5%9B%BE20220503092755.png"> <div class="blogger-info"><h3>lingxin</h3> <span>凌歆</span></div></div> <nav class="nav-links"><div class="nav-item"><a href="/" class="nav-link">首页</a></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="前端" class="dropdown-title"><a href="/web/" class="link-title">前端</a> <span class="title" style="display:none;">前端</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><h4>学习笔记</h4> <ul class="dropdown-subitem-wrapper"><li class="dropdown-subitem"><a href="/note/html/" class="nav-link">HTML笔记</a></li><li class="dropdown-subitem"><a href="/note/js-low/" class="nav-link">JavaScript基础笔记</a></li><li class="dropdown-subitem"><a href="/note/js-high/" class="nav-link">JavaScript高阶笔记</a></li><li class="dropdown-subitem"><a href="/note/js-dom-bom/" class="nav-link">JavaScript DOM和BOM笔记</a></li><li class="dropdown-subitem"><a href="/note/jquery/" class="nav-link">jQuery笔记</a></li><li class="dropdown-subitem"><a href="/note/ajax/" class="nav-link">Ajax笔记</a></li><li class="dropdown-subitem"><a href="/note/nodejs/" class="nav-link">NodeJs笔记</a></li><li class="dropdown-subitem"><a href="/note/reg/" class="nav-link">正则表达式笔记</a></li><li class="dropdown-subitem"><a href="/note/vue/" class="nav-link">Vue笔记</a></li><li class="dropdown-subitem"><a href="/note/react/" class="nav-link">react笔记</a></li><li class="dropdown-subitem"><a href="/note/wx/" class="nav-link">微信小程序笔记</a></li><li class="dropdown-subitem"><a href="/note/uniapp/" class="nav-link">uniapp笔记</a></li><li class="dropdown-subitem"><a href="/note/echarts/" class="nav-link">echarts笔记</a></li><li class="dropdown-subitem"><a href="/note/git/" class="nav-link">Git笔记</a></li></ul></li></ul></div></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="后端" class="dropdown-title"><a href="/back/" class="link-title">后端</a> <span class="title" style="display:none;">后端</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/note/java/" class="nav-link">JAVA</a></li><li class="dropdown-item"><!----> <a href="/note/javaweb/" class="nav-link">JavaWeb</a></li><li class="dropdown-item"><!----> <a href="/note/mysql/" class="nav-link">MySql</a></li><li class="dropdown-item"><!----> <a href="/note/ssm/" class="nav-link">ssm</a></li></ul></div></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="算法" class="dropdown-title"><a href="/algor/" class="link-title">算法</a> <span class="title" style="display:none;">算法</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/note/sf/" class="nav-link">算法训练营</a></li><li class="dropdown-item"><!----> <a href="/note/js-sf/" class="nav-link">js数据结构与算法</a></li></ul></div></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="面试" class="dropdown-title"><a href="/mianshi/" class="link-title">面试</a> <span class="title" style="display:none;">面试</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/note/lqb/" class="nav-link">蓝桥杯备战</a></li><li class="dropdown-item"><!----> <a href="/note/ms/" class="nav-link">前端面试</a></li><li class="dropdown-item"><!----> <a href="/note/hmms/" class="nav-link">黑马面试</a></li><li class="dropdown-item"><!----> <a href="/note/xzms/" class="nav-link">校招零距离面试</a></li></ul></div></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="解决方案" class="dropdown-title"><a href="/resolve/" class="link-title">解决方案</a> <span class="title" style="display:none;">解决方案</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/note/qd-resolve/" class="nav-link">前端解决方案</a></li><li class="dropdown-item"><!----> <a href="/note/hd-resolve/" class="nav-link">后端解决方案</a></li></ul></div></div><div class="nav-item"><a href="/pages/beb6c0bd8a66cea6/" class="nav-link">收藏</a></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="索引" class="dropdown-title"><a href="/archives/" class="link-title">索引</a> <span class="title" style="display:none;">索引</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/categories/" class="nav-link">分类</a></li><li class="dropdown-item"><!----> <a href="/tags/" class="nav-link">标签</a></li><li class="dropdown-item"><!----> <a href="/archives/" class="nav-link">归档</a></li></ul></div></div> <a href="https://github.com/linxin1123/vuepress-blog" target="_blank" rel="noopener noreferrer" class="repo-link">
    GitHub
    <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></nav>  <ul class="sidebar-links"><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading"><span>学习笔记</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading"><span>Java笔记</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading"><span>JavaWeb笔记</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading"><span>MySql笔记</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading open"><span>SSM笔记</span> <span class="arrow down"></span></p> <ul class="sidebar-links sidebar-group-items"><li><a href="/pages/d90431/" aria-current="page" class="active sidebar-link">SSM复习-cnblog</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header level2"><a href="/pages/d90431/#依赖注入-注入配置文件中的属性名" class="sidebar-link">依赖注入，注入配置文件中的属性名</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header level3"><a href="/pages/d90431/#_1-2-加载properties文件" class="sidebar-link">1.2 加载properties文件</a></li><li class="sidebar-sub-header level4"><a href="/pages/d90431/#_1-2-1-第三方bean属性优化" class="sidebar-link">1.2.1 第三方bean属性优化</a></li><li class="sidebar-sub-header level5"><a href="/pages/d90431/#_1-2-1-1-实现思路" class="sidebar-link">1.2.1.1 实现思路</a></li><li class="sidebar-sub-header level5"><a href="/pages/d90431/#_1-2-1-2-实现步骤" class="sidebar-link">1.2.1.2 实现步骤</a></li><li class="sidebar-sub-header level6"><a href="/pages/d90431/#步骤1-准备properties配置文件" class="sidebar-link">步骤1:准备properties配置文件</a></li><li class="sidebar-sub-header level6"><a href="/pages/d90431/#步骤2-开启context命名空间" class="sidebar-link">步骤2:开启context命名空间</a></li><li class="sidebar-sub-header level6"><a href="/pages/d90431/#步骤3-加载properties配置文件" class="sidebar-link">步骤3:加载properties配置文件</a></li><li class="sidebar-sub-header level6"><a href="/pages/d90431/#步骤4-完成属性注入" class="sidebar-link">步骤4:完成属性注入</a></li></ul></li><li class="sidebar-sub-header level2"><a href="/pages/d90431/#spring事务管理-日志数据库的解决方案" class="sidebar-link">spring事务管理---日志数据库的解决方案</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header level4"><a href="/pages/d90431/#_6-3-2-转账业务追加日志案例" class="sidebar-link">6.3.2 转账业务追加日志案例</a></li><li class="sidebar-sub-header level5"><a href="/pages/d90431/#_6-3-2-1-需求分析" class="sidebar-link">6.3.2.1 需求分析</a></li><li class="sidebar-sub-header level5"><a href="/pages/d90431/#_6-3-2-2-环境准备" class="sidebar-link">6.3.2.2 环境准备</a></li><li class="sidebar-sub-header level6"><a href="/pages/d90431/#步骤1-创建日志表" class="sidebar-link">步骤1:创建日志表</a></li><li class="sidebar-sub-header level6"><a href="/pages/d90431/#步骤2-添加logdao接口" class="sidebar-link">步骤2:添加LogDao接口</a></li><li class="sidebar-sub-header level6"><a href="/pages/d90431/#步骤3-添加logservice接口与实现类" class="sidebar-link">步骤3:添加LogService接口与实现类</a></li><li class="sidebar-sub-header level6"><a href="/pages/d90431/#步骤4-在转账的业务中添加记录日志" class="sidebar-link">步骤4:在转账的业务中添加记录日志</a></li><li class="sidebar-sub-header level6"><a href="/pages/d90431/#步骤5-运行程序" class="sidebar-link">步骤5:运行程序</a></li><li class="sidebar-sub-header level4"><a href="/pages/d90431/#_6-3-3-事务传播行为" class="sidebar-link">6.3.3 事务传播行为</a></li><li class="sidebar-sub-header level5"><a href="/pages/d90431/#_1-修改logservice改变事务的传播行为" class="sidebar-link">1.修改logService改变事务的传播行为</a></li><li class="sidebar-sub-header level5"><a href="/pages/d90431/#_2-事务传播行为的可选值" class="sidebar-link">2.事务传播行为的可选值</a></li></ul></li><li class="sidebar-sub-header level2"><a href="/pages/d90431/#get请求中文乱码-使用springmvc-还没有springboot" class="sidebar-link">GET请求中文乱码(使用springMVC，还没有springboot)</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header level5"><a href="/pages/d90431/#post发送参数" class="sidebar-link">POST发送参数</a></li><li class="sidebar-sub-header level5"><a href="/pages/d90431/#post请求中文乱码" class="sidebar-link">POST请求中文乱码</a></li></ul></li><li class="sidebar-sub-header level2"><a href="/pages/d90431/#_4-3-五种类型参数传递-非json" class="sidebar-link">4.3 五种类型参数传递(非json)</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header level3"><a href="/pages/d90431/#而是表单或者地址栏参数" class="sidebar-link">而是表单或者地址栏参数</a></li><li class="sidebar-sub-header level4"><a href="/pages/d90431/#_4-3-1-普通参数" class="sidebar-link">4.3.1 普通参数</a></li><li class="sidebar-sub-header level4"><a href="/pages/d90431/#_4-3-2-pojo数据类型" class="sidebar-link">4.3.2 POJO数据类型</a></li><li class="sidebar-sub-header level4"><a href="/pages/d90431/#_4-3-3-嵌套pojo类型参数" class="sidebar-link">4.3.3 嵌套POJO类型参数</a></li><li class="sidebar-sub-header level4"><a href="/pages/d90431/#_4-3-4-数组类型参数" class="sidebar-link">4.3.4 数组类型参数</a></li><li class="sidebar-sub-header level4"><a href="/pages/d90431/#_4-3-5-集合类型参数" class="sidebar-link">4.3.5 ==集合类型参数==</a></li></ul></li><li class="sidebar-sub-header level2"><a href="/pages/d90431/#_4-4-json数据传输参数" class="sidebar-link">4.4 JSON数据传输参数</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header level4"><a href="/pages/d90431/#json普通数组" class="sidebar-link">JSON普通数组</a></li><li class="sidebar-sub-header level6"><a href="/pages/d90431/#步骤1-pom-xml添加依赖" class="sidebar-link">步骤1:pom.xml添加依赖</a></li><li class="sidebar-sub-header level6"><a href="/pages/d90431/#步骤2-postman发送json数据" class="sidebar-link">步骤2:PostMan发送JSON数据</a></li><li class="sidebar-sub-header level6"><a href="/pages/d90431/#步骤3-开启springmvc注解支持" class="sidebar-link">步骤3:开启SpringMVC注解支持</a></li><li class="sidebar-sub-header level6"><a href="/pages/d90431/#步骤4-参数前添加-requestbody" class="sidebar-link">步骤4:参数前添加@RequestBody</a></li><li class="sidebar-sub-header level6"><a href="/pages/d90431/#步骤5-启动运行程序" class="sidebar-link">步骤5:启动运行程序</a></li><li class="sidebar-sub-header level4"><a href="/pages/d90431/#json对象数据" class="sidebar-link">JSON对象数据</a></li><li class="sidebar-sub-header level4"><a href="/pages/d90431/#json对象数组" class="sidebar-link">JSON对象数组</a></li><li class="sidebar-sub-header level4"><a href="/pages/d90431/#知识点1-enablewebmvc" class="sidebar-link">知识点1：@EnableWebMvc</a></li><li class="sidebar-sub-header level4"><a href="/pages/d90431/#知识点2-requestbody" class="sidebar-link">知识点2：@RequestBody</a></li><li class="sidebar-sub-header level4"><a href="/pages/d90431/#requestbody与-requestparam区别" class="sidebar-link">@RequestBody与@RequestParam区别</a></li></ul></li><li class="sidebar-sub-header level2"><a href="/pages/d90431/#_4-5-日期类型参数传递" class="sidebar-link">4.5 日期类型参数传递</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header level4"><a href="/pages/d90431/#步骤1-编写方法接收日期数据" class="sidebar-link">步骤1:编写方法接收日期数据</a></li><li class="sidebar-sub-header level4"><a href="/pages/d90431/#步骤2-启动tomcat服务器" class="sidebar-link">步骤2:启动Tomcat服务器</a></li><li class="sidebar-sub-header level4"><a href="/pages/d90431/#步骤3-使用postman发送请求" class="sidebar-link">步骤3:使用PostMan发送请求</a></li><li class="sidebar-sub-header level4"><a href="/pages/d90431/#步骤4-查看控制台" class="sidebar-link">步骤4:查看控制台</a></li><li class="sidebar-sub-header level4"><a href="/pages/d90431/#步骤5-更换日期格式" class="sidebar-link">步骤5:更换日期格式</a></li><li class="sidebar-sub-header level4"><a href="/pages/d90431/#步骤6-携带时间的日期" class="sidebar-link">步骤6:携带时间的日期</a></li><li class="sidebar-sub-header level4"><a href="/pages/d90431/#知识点1-datetimeformat" class="sidebar-link">知识点1：@DateTimeFormat</a></li><li class="sidebar-sub-header level4"><a href="/pages/d90431/#内部实现原理" class="sidebar-link">内部实现原理</a></li></ul></li><li class="sidebar-sub-header level2"><a href="/pages/d90431/#_5-4-3-页面访问处理" class="sidebar-link">5.4.3 页面访问处理</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header level5"><a href="/pages/d90431/#步骤1-拷贝静态页面" class="sidebar-link">步骤1:拷贝静态页面</a></li><li class="sidebar-sub-header level5"><a href="/pages/d90431/#步骤2-访问pages目录下的books-html" class="sidebar-link">步骤2:访问pages目录下的books.html</a></li><li class="sidebar-sub-header level5"><a href="/pages/d90431/#步骤3-修改books-html页面" class="sidebar-link">步骤3:修改books.html页面</a></li></ul></li><li class="sidebar-sub-header level2"><a href="/pages/d90431/#springboot-配置文件无提示" class="sidebar-link">springboot 配置文件无提示</a></li><li class="sidebar-sub-header level2"><a href="/pages/d90431/#springboot-配置文件读取" class="sidebar-link">springBoot 配置文件读取</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header level3"><a href="/pages/d90431/#_2-3-yaml配置文件数据读取" class="sidebar-link">2.3  yaml配置文件数据读取</a></li><li class="sidebar-sub-header level4"><a href="/pages/d90431/#_2-3-1-环境准备" class="sidebar-link">2.3.1  环境准备</a></li><li class="sidebar-sub-header level4"><a href="/pages/d90431/#_2-3-2-读取配置数据" class="sidebar-link">2.3.2  读取配置数据</a></li><li class="sidebar-sub-header level5"><a href="/pages/d90431/#_2-3-2-1-使用-value注解" class="sidebar-link">2.3.2.1  使用 @Value注解</a></li><li class="sidebar-sub-header level5"><a href="/pages/d90431/#_2-3-2-2-environment对象" class="sidebar-link">2.3.2.2  Environment对象</a></li><li class="sidebar-sub-header level5"><a href="/pages/d90431/#_2-3-2-3-自定义对象" class="sidebar-link">2.3.2.3  自定义对象</a></li><li class="sidebar-sub-header level3"><a href="/pages/d90431/#_2-4-多环境配置" class="sidebar-link">2.4  多环境配置</a></li><li class="sidebar-sub-header level4"><a href="/pages/d90431/#_2-4-1-yaml文件" class="sidebar-link">2.4.1  yaml文件</a></li><li class="sidebar-sub-header level4"><a href="/pages/d90431/#_2-4-2-properties文件" class="sidebar-link">2.4.2  properties文件</a></li><li class="sidebar-sub-header level4"><a href="/pages/d90431/#_2-4-3-命令行启动参数设置" class="sidebar-link">2.4.3  命令行启动参数设置</a></li><li class="sidebar-sub-header level3"><a href="/pages/d90431/#_2-5-配置文件分类" class="sidebar-link">2.5  配置文件分类</a></li><li class="sidebar-sub-header level4"><a href="/pages/d90431/#_2-5-1-代码演示" class="sidebar-link">2.5.1  代码演示</a></li><li class="sidebar-sub-header level5"><a href="/pages/d90431/#_2-5-1-1-环境准备" class="sidebar-link">2.5.1.1  环境准备</a></li><li class="sidebar-sub-header level5"><a href="/pages/d90431/#_2-5-1-2-验证1级和2级的优先级" class="sidebar-link">2.5.1.2  验证1级和2级的优先级</a></li><li class="sidebar-sub-header level5"><a href="/pages/d90431/#_2-5-1-3-验证2级和4级的优先级" class="sidebar-link">2.5.1.3  验证2级和4级的优先级</a></li></ul></li><li class="sidebar-sub-header level2"><a href="/pages/d90431/#mybatis-plus-使用时的特殊情况" class="sidebar-link">mybatis-plus 使用时的特殊情况</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header level3"><a href="/pages/d90431/#_3-4-映射匹配兼容性" class="sidebar-link">3.4 映射匹配兼容性</a></li><li class="sidebar-sub-header level4"><a href="/pages/d90431/#问题1-表字段与编码属性设计不同步" class="sidebar-link">问题1:表字段与编码属性设计不同步</a></li><li class="sidebar-sub-header level4"><a href="/pages/d90431/#问题2-编码中添加了数据库中未定义的属性" class="sidebar-link">问题2:编码中添加了数据库中未定义的属性</a></li><li class="sidebar-sub-header level4"><a href="/pages/d90431/#问题3-采用默认查询开放了更多的字段查看权限" class="sidebar-link">问题3：采用默认查询开放了更多的字段查看权限</a></li><li class="sidebar-sub-header level4"><a href="/pages/d90431/#知识点1-tablefield" class="sidebar-link">知识点1：@TableField</a></li><li class="sidebar-sub-header level4"><a href="/pages/d90431/#问题4-表名与编码开发设计不同步" class="sidebar-link">问题4:表名与编码开发设计不同步</a></li><li class="sidebar-sub-header level4"><a href="/pages/d90431/#知识点2-tablename" class="sidebar-link">知识点2：@TableName</a></li><li class="sidebar-sub-header level4"><a href="/pages/d90431/#代码演示" class="sidebar-link">代码演示</a></li><li class="sidebar-sub-header level5"><a href="/pages/d90431/#步骤1-修改数据库表user为tbl-user" class="sidebar-link">步骤1:修改数据库表user为tbl_user</a></li><li class="sidebar-sub-header level5"><a href="/pages/d90431/#步骤2-模型类添加-tablename注解" class="sidebar-link">步骤2:模型类添加@TableName注解</a></li><li class="sidebar-sub-header level5"><a href="/pages/d90431/#步骤3-将字段password修改成pwd" class="sidebar-link">步骤3:将字段password修改成pwd</a></li><li class="sidebar-sub-header level5"><a href="/pages/d90431/#步骤4-使用-tablefield映射关系" class="sidebar-link">步骤4：使用@TableField映射关系</a></li><li class="sidebar-sub-header level5"><a href="/pages/d90431/#步骤5-添加一个数据库表不存在的字段" class="sidebar-link">步骤5:添加一个数据库表不存在的字段</a></li><li class="sidebar-sub-header level5"><a href="/pages/d90431/#步骤6-使用-tablefield排除字段" class="sidebar-link">步骤6：使用@TableField排除字段</a></li><li class="sidebar-sub-header level5"><a href="/pages/d90431/#步骤7-查询时将pwd隐藏" class="sidebar-link">步骤7:查询时将pwd隐藏</a></li></ul></li><li class="sidebar-sub-header level2"><a href="/pages/d90431/#mybatis-plus逻辑删除-delete字段" class="sidebar-link">mybatis-plus逻辑删除（delete字段）</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header level3"><a href="/pages/d90431/#_4-3-逻辑删除" class="sidebar-link">4.3 逻辑删除</a></li><li class="sidebar-sub-header level4"><a href="/pages/d90431/#步骤1-修改数据库表添加deleted列" class="sidebar-link">步骤1:修改数据库表添加deleted列</a></li><li class="sidebar-sub-header level4"><a href="/pages/d90431/#步骤2-实体类添加属性" class="sidebar-link">步骤2:实体类添加属性</a></li><li class="sidebar-sub-header level4"><a href="/pages/d90431/#步骤3-运行删除方法" class="sidebar-link">步骤3:运行删除方法</a></li><li class="sidebar-sub-header level4"><a href="/pages/d90431/#知识点1-tablelogic" class="sidebar-link">知识点1：@TableLogic</a></li></ul></li></ul></li></ul></section></li></ul> </aside> <div><main class="page"><div class="theme-vdoing-wrapper "><div class="articleInfo-wrap" data-v-06225672><div class="articleInfo" data-v-06225672><ul class="breadcrumbs" data-v-06225672><li data-v-06225672><a href="/" title="首页" class="iconfont icon-home router-link-active" data-v-06225672></a></li> <li data-v-06225672><a href="/back/#后端" data-v-06225672>后端</a></li><li data-v-06225672><a href="/back/#SSM笔记" data-v-06225672>SSM笔记</a></li></ul> <div class="info" data-v-06225672><div title="作者" class="author iconfont icon-touxiang" data-v-06225672><a href="https://github.com/linxin1123" target="_blank" title="作者" class="beLink" data-v-06225672>lingxin</a></div> <div title="创建时间" class="date iconfont icon-riqi" data-v-06225672><a href="javascript:;" data-v-06225672>2023-02-17</a></div> <!----></div></div></div> <!----> <div class="content-wrapper"><div class="right-menu-wrapper"><div class="right-menu-margin"><div class="right-menu-title">目录</div> <div class="right-menu-content"></div></div></div> <h1><img src="">SSM复习-cnblog<!----></h1>  <div class="theme-vdoing-content content__default"><h2 id="依赖注入-注入配置文件中的属性名"><a href="#依赖注入-注入配置文件中的属性名" class="header-anchor">#</a> 依赖注入，注入配置文件中的属性名</h2> <h3 id="_1-2-加载properties文件"><a href="#_1-2-加载properties文件" class="header-anchor">#</a> 1.2 加载properties文件</h3> <p>上节中我们已经完成两个数据源<code>druid</code>和<code>C3P0</code>的配置，但是其中包含了一些问题，我们来分析下:</p> <ul><li>这两个数据源中都使用到了一些固定的常量如数据库连接四要素，把这些值写在Spring的配置文件中不利于后期维护</li> <li>需要将这些值提取到一个外部的properties配置文件中</li> <li>Spring框架如何从配置文件中读取属性值来配置就是接下来要解决的问题。</li></ul> <p>问题提出来后，具体该如何实现?</p> <h4 id="_1-2-1-第三方bean属性优化"><a href="#_1-2-1-第三方bean属性优化" class="header-anchor">#</a> 1.2.1 第三方bean属性优化</h4> <h5 id="_1-2-1-1-实现思路"><a href="#_1-2-1-1-实现思路" class="header-anchor">#</a> 1.2.1.1 实现思路</h5> <blockquote><p>需求:将数据库连接四要素提取到properties配置文件，spring来加载配置信息并使用这些信息来完成属性注入。</p> <p>1.在resources下创建一个jdbc.properties(文件的名称可以任意)</p> <p>2.将数据库连接四要素配置到配置文件中</p> <p>3.在Spring的配置文件中加载properties文件</p> <p>4.使用加载到的值实现属性注入</p> <p>其中第3，4步骤是需要大家重点关注，具体是如何实现。</p></blockquote> <h5 id="_1-2-1-2-实现步骤"><a href="#_1-2-1-2-实现步骤" class="header-anchor">#</a> 1.2.1.2 实现步骤</h5> <h6 id="步骤1-准备properties配置文件"><a href="#步骤1-准备properties配置文件" class="header-anchor">#</a> 步骤1:准备properties配置文件</h6> <p>resources下创建一个jdbc.properties文件,并添加对应的属性键值对</p> <div class="language-properties line-numbers-mode"><pre class="language-properties"><code><span class="token key attr-name">jdbc.driver</span><span class="token punctuation">=</span><span class="token value attr-value">com.mysql.jdbc.Driver</span>
<span class="token key attr-name">jdbc.url</span><span class="token punctuation">=</span><span class="token value attr-value">jdbc:mysql://127.0.0.1:3306/spring_db</span>
<span class="token key attr-name">jdbc.username</span><span class="token punctuation">=</span><span class="token value attr-value">root</span>
<span class="token key attr-name">jdbc.password</span><span class="token punctuation">=</span><span class="token value attr-value">root</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br></div></div><h6 id="步骤2-开启context命名空间"><a href="#步骤2-开启context命名空间" class="header-anchor">#</a> 步骤2:开启<code>context</code>命名空间</h6> <ul><li>applicationContext.xml</li></ul> <p><img src="https://img2023.cnblogs.com/blog/3089561/202302/3089561-20230203225142473-1208922177.png" alt=""></p> <p>在applicationContext.xml中开<code>context</code>命名空间</p> <div class="language-xml line-numbers-mode"><pre class="language-xml"><code><span class="token prolog">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;</span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>beans</span> <span class="token attr-name">xmlns</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>http://www.springframework.org/schema/beans<span class="token punctuation">&quot;</span></span>
       <span class="token attr-name"><span class="token namespace">xmlns:</span>xsi</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>http://www.w3.org/2001/XMLSchema-instance<span class="token punctuation">&quot;</span></span>
       <span class="token attr-name"><span class="token namespace">xmlns:</span>context</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>http://www.springframework.org/schema/context<span class="token punctuation">&quot;</span></span>
       <span class="token attr-name"><span class="token namespace">xsi:</span>schemaLocation</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>
            http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context.xsd<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>beans</span><span class="token punctuation">&gt;</span></span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br></div></div><h6 id="步骤3-加载properties配置文件"><a href="#步骤3-加载properties配置文件" class="header-anchor">#</a> 步骤3:加载properties配置文件</h6> <p>在配置文件中使用<code>context</code>命名空间下的标签来加载properties配置文件</p> <div class="language-xml line-numbers-mode"><pre class="language-xml"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token namespace">context:</span>property-placeholder</span> <span class="token attr-name">location</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>jdbc.properties<span class="token punctuation">&quot;</span></span><span class="token punctuation">/&gt;</span></span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br></div></div><h6 id="步骤4-完成属性注入"><a href="#步骤4-完成属性注入" class="header-anchor">#</a> 步骤4:完成属性注入</h6> <p>使用<code>${key}</code>来读取properties配置文件中的内容并完成属性注入</p> <div class="language-xml line-numbers-mode"><pre class="language-xml"><code><span class="token prolog">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;</span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>beans</span> <span class="token attr-name">xmlns</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>http://www.springframework.org/schema/beans<span class="token punctuation">&quot;</span></span>
       <span class="token attr-name"><span class="token namespace">xmlns:</span>xsi</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>http://www.w3.org/2001/XMLSchema-instance<span class="token punctuation">&quot;</span></span>
       <span class="token attr-name"><span class="token namespace">xmlns:</span>context</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>http://www.springframework.org/schema/context<span class="token punctuation">&quot;</span></span>
       <span class="token attr-name"><span class="token namespace">xsi:</span>schemaLocation</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>
            http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context.xsd<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
    
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token namespace">context:</span>property-placeholder</span> <span class="token attr-name">location</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>jdbc.properties<span class="token punctuation">&quot;</span></span><span class="token punctuation">/&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>bean</span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>dataSource<span class="token punctuation">&quot;</span></span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>com.alibaba.druid.pool.DruidDataSource<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>property</span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>driverClassName<span class="token punctuation">&quot;</span></span> <span class="token attr-name">value</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>${jdbc.driver}<span class="token punctuation">&quot;</span></span><span class="token punctuation">/&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>property</span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>url<span class="token punctuation">&quot;</span></span> <span class="token attr-name">value</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>${jdbc.url}<span class="token punctuation">&quot;</span></span><span class="token punctuation">/&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>property</span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>username<span class="token punctuation">&quot;</span></span> <span class="token attr-name">value</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>${jdbc.username}<span class="token punctuation">&quot;</span></span><span class="token punctuation">/&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>property</span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>password<span class="token punctuation">&quot;</span></span> <span class="token attr-name">value</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>${jdbc.password}<span class="token punctuation">&quot;</span></span><span class="token punctuation">/&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>bean</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>beans</span><span class="token punctuation">&gt;</span></span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br></div></div><p>至此，读取外部properties配置文件中的内容就已经完成。</p> <h2 id="spring事务管理-日志数据库的解决方案"><a href="#spring事务管理-日志数据库的解决方案" class="header-anchor">#</a> spring事务管理---日志数据库的解决方案</h2> <h4 id="_6-3-2-转账业务追加日志案例"><a href="#_6-3-2-转账业务追加日志案例" class="header-anchor">#</a> 6.3.2 转账业务追加日志案例</h4> <h5 id="_6-3-2-1-需求分析"><a href="#_6-3-2-1-需求分析" class="header-anchor">#</a> 6.3.2.1 需求分析</h5> <p>在前面的转案例的基础上添加新的需求，完成转账后记录日志。</p> <ul><li>需求：实现任意两个账户间转账操作，并对每次转账操作在数据库进行留痕</li> <li>需求微缩：A账户减钱，B账户加钱，数据库记录日志</li></ul> <p>基于上述的业务需求，我们来分析下该如何实现:</p> <p>①：基于转账操作案例添加日志模块，实现数据库中记录日志</p> <p>②：业务层转账操作（transfer），调用减钱、加钱与记录日志功能</p> <p>需要注意一点就是，我们这个案例的预期效果为:</p> <p>==无论转账操作是否成功，均进行转账操作的日志留痕==</p> <h5 id="_6-3-2-2-环境准备"><a href="#_6-3-2-2-环境准备" class="header-anchor">#</a> 6.3.2.2 环境准备</h5> <p>该环境是基于转账环境来完成的，所以环境的准备可以参考<code>6.1.3的环境搭建步骤</code>，在其基础上，我们继续往下写</p> <h6 id="步骤1-创建日志表"><a href="#步骤1-创建日志表" class="header-anchor">#</a> 步骤1:创建日志表</h6> <div class="language-sql line-numbers-mode"><pre class="language-sql"><code><span class="token keyword">create</span> <span class="token keyword">table</span> tbl_log<span class="token punctuation">(</span>
   id <span class="token keyword">int</span> <span class="token keyword">primary</span> <span class="token keyword">key</span> <span class="token keyword">auto_increment</span><span class="token punctuation">,</span>
   info <span class="token keyword">varchar</span><span class="token punctuation">(</span><span class="token number">255</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
   createDate <span class="token keyword">datetime</span>
<span class="token punctuation">)</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br></div></div><h6 id="步骤2-添加logdao接口"><a href="#步骤2-添加logdao接口" class="header-anchor">#</a> 步骤2:添加LogDao接口</h6> <div class="language-java line-numbers-mode"><pre class="language-java"><code><span class="token keyword">public</span> <span class="token keyword">interface</span> <span class="token class-name">LogDao</span> <span class="token punctuation">{</span>
    <span class="token annotation punctuation">@Insert</span><span class="token punctuation">(</span><span class="token string">&quot;insert into tbl_log (info,createDate) values(#{info},now())&quot;</span><span class="token punctuation">)</span>
    <span class="token keyword">void</span> <span class="token function">log</span><span class="token punctuation">(</span><span class="token class-name">String</span> info<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br></div></div><h6 id="步骤3-添加logservice接口与实现类"><a href="#步骤3-添加logservice接口与实现类" class="header-anchor">#</a> 步骤3:添加LogService接口与实现类</h6> <div class="language-java line-numbers-mode"><pre class="language-java"><code><span class="token keyword">public</span> <span class="token keyword">interface</span> <span class="token class-name">LogService</span> <span class="token punctuation">{</span>
    <span class="token keyword">void</span> <span class="token function">log</span><span class="token punctuation">(</span><span class="token class-name">String</span> out<span class="token punctuation">,</span> <span class="token class-name">String</span> in<span class="token punctuation">,</span> <span class="token class-name">Double</span> money<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token annotation punctuation">@Service</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">LogServiceImpl</span> <span class="token keyword">implements</span> <span class="token class-name">LogService</span> <span class="token punctuation">{</span>

    <span class="token annotation punctuation">@Autowired</span>
    <span class="token keyword">private</span> <span class="token class-name">LogDao</span> logDao<span class="token punctuation">;</span>
	<span class="token annotation punctuation">@Transactional</span>
    <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">log</span><span class="token punctuation">(</span><span class="token class-name">String</span> out<span class="token punctuation">,</span><span class="token class-name">String</span> in<span class="token punctuation">,</span><span class="token class-name">Double</span> money <span class="token punctuation">)</span> <span class="token punctuation">{</span>
        logDao<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">&quot;转账操作由&quot;</span><span class="token operator">+</span>out<span class="token operator">+</span><span class="token string">&quot;到&quot;</span><span class="token operator">+</span>in<span class="token operator">+</span><span class="token string">&quot;,金额：&quot;</span><span class="token operator">+</span>money<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br></div></div><h6 id="步骤4-在转账的业务中添加记录日志"><a href="#步骤4-在转账的业务中添加记录日志" class="header-anchor">#</a> 步骤4:在转账的业务中添加记录日志</h6> <div class="language-java line-numbers-mode"><pre class="language-java"><code><span class="token keyword">public</span> <span class="token keyword">interface</span> <span class="token class-name">AccountService</span> <span class="token punctuation">{</span>
    <span class="token comment">/**
     * 转账操作
     * @param out 传出方
     * @param in 转入方
     * @param money 金额
     */</span>
    <span class="token comment">//配置当前接口方法具有事务</span>
    <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">transfer</span><span class="token punctuation">(</span><span class="token class-name">String</span> out<span class="token punctuation">,</span><span class="token class-name">String</span> in <span class="token punctuation">,</span><span class="token class-name">Double</span> money<span class="token punctuation">)</span><span class="token keyword">throws</span> <span class="token class-name">IOException</span> <span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token annotation punctuation">@Service</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">AccountServiceImpl</span> <span class="token keyword">implements</span> <span class="token class-name">AccountService</span> <span class="token punctuation">{</span>

    <span class="token annotation punctuation">@Autowired</span>
    <span class="token keyword">private</span> <span class="token class-name">AccountDao</span> accountDao<span class="token punctuation">;</span>
    <span class="token annotation punctuation">@Autowired</span>
    <span class="token keyword">private</span> <span class="token class-name">LogService</span> logService<span class="token punctuation">;</span>
	<span class="token annotation punctuation">@Transactional</span>
    <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">transfer</span><span class="token punctuation">(</span><span class="token class-name">String</span> out<span class="token punctuation">,</span><span class="token class-name">String</span> in <span class="token punctuation">,</span><span class="token class-name">Double</span> money<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">try</span><span class="token punctuation">{</span>
            accountDao<span class="token punctuation">.</span><span class="token function">outMoney</span><span class="token punctuation">(</span>out<span class="token punctuation">,</span>money<span class="token punctuation">)</span><span class="token punctuation">;</span>
            accountDao<span class="token punctuation">.</span><span class="token function">inMoney</span><span class="token punctuation">(</span>in<span class="token punctuation">,</span>money<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span><span class="token keyword">finally</span> <span class="token punctuation">{</span>
            logService<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>out<span class="token punctuation">,</span>in<span class="token punctuation">,</span>money<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
    <span class="token punctuation">}</span>

<span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br><span class="line-number">27</span><br><span class="line-number">28</span><br></div></div><h6 id="步骤5-运行程序"><a href="#步骤5-运行程序" class="header-anchor">#</a> 步骤5:运行程序</h6> <ul><li><p>当程序正常运行，tbl_account表中转账成功，tbl_log表中日志记录成功</p></li> <li><p>当转账业务之间出现异常(int i =1/0),转账失败，tbl_account成功回滚，但是tbl_log表未添加数据</p></li> <li><p>这个结果和我们想要的不一样，什么原因?该如何解决?</p></li> <li><p>失败原因:日志的记录与转账操作隶属同一个事务，同成功同失败</p></li> <li><p>最终效果:无论转账操作是否成功，日志必须保留</p></li></ul> <h4 id="_6-3-3-事务传播行为"><a href="#_6-3-3-事务传播行为" class="header-anchor">#</a> 6.3.3 事务传播行为</h4> <p><img src="https://img2023.cnblogs.com/blog/3089561/202302/3089561-20230203225141972-1640455487.png" alt="1630253779575"></p> <p>对于上述案例的分析:</p> <ul><li>log方法、inMoney方法和outMoney方法都属于增删改，分别有事务T1,T2,T3</li> <li>transfer因为加了@Transactional注解，也开启了事务T</li> <li>前面我们讲过Spring事务会把T1,T2,T3都加入到事务T中</li> <li>所以当转账失败后，所有的事务都回滚，导致日志没有记录下来</li> <li>这和我们的需求不符，这个时候我们就想能不能让log方法单独是一个事务呢?</li></ul> <p>要想解决这个问题，就需要用到事务传播行为，所谓的事务传播行为指的是:</p> <p>事务传播行为：事务协调员对事务管理员所携带事务的处理态度。</p> <p>具体如何解决，就需要用到之前我们没有说的<code>propagation属性</code>。</p> <h5 id="_1-修改logservice改变事务的传播行为"><a href="#_1-修改logservice改变事务的传播行为" class="header-anchor">#</a> 1.修改logService改变事务的传播行为</h5> <div class="language-java line-numbers-mode"><pre class="language-java"><code><span class="token annotation punctuation">@Service</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">LogServiceImpl</span> <span class="token keyword">implements</span> <span class="token class-name">LogService</span> <span class="token punctuation">{</span>

    <span class="token annotation punctuation">@Autowired</span>
    <span class="token keyword">private</span> <span class="token class-name">LogDao</span> logDao<span class="token punctuation">;</span>
	<span class="token comment">//propagation设置事务属性：传播行为设置为当前操作需要新事务</span>
    <span class="token annotation punctuation">@Transactional</span><span class="token punctuation">(</span>propagation <span class="token operator">=</span> <span class="token class-name">Propagation</span><span class="token punctuation">.</span><span class="token constant">REQUIRES_NEW</span><span class="token punctuation">)</span>
    <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">log</span><span class="token punctuation">(</span><span class="token class-name">String</span> out<span class="token punctuation">,</span><span class="token class-name">String</span> in<span class="token punctuation">,</span><span class="token class-name">Double</span> money <span class="token punctuation">)</span> <span class="token punctuation">{</span>
        logDao<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">&quot;转账操作由&quot;</span><span class="token operator">+</span>out<span class="token operator">+</span><span class="token string">&quot;到&quot;</span><span class="token operator">+</span>in<span class="token operator">+</span><span class="token string">&quot;,金额：&quot;</span><span class="token operator">+</span>money<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br></div></div><p>运行后，就能实现我们想要的结果，不管转账是否成功，都会记录日志。</p> <h5 id="_2-事务传播行为的可选值"><a href="#_2-事务传播行为的可选值" class="header-anchor">#</a> 2.事务传播行为的可选值</h5> <p><img src="https://img2023.cnblogs.com/blog/3089561/202302/3089561-20230203225141317-1880383122.png" alt="1630254257628"></p> <p>对于我们开发实际中使用的话，因为默认值需要事务是常态的。根据开发过程选择其他的就可以了，例如案例中需要新事务就需要手工配置。其实入账和出账操作上也有事务，采用的就是默认值。</p> <h2 id="get请求中文乱码-使用springmvc-还没有springboot"><a href="#get请求中文乱码-使用springmvc-还没有springboot" class="header-anchor">#</a> GET请求中文乱码(使用springMVC，还没有springboot)</h2> <p>如果我们传递的参数中有中文，你会发现接收到的参数会出现中文乱码问题。</p> <p>发送请求:<code>http://localhost/commonParam?name=张三&amp;age=18</code></p> <p>控制台:</p> <p><img src="https://img2023.cnblogs.com/blog/3089561/202302/3089561-20230203225140847-429220377.png" alt="1630480536510"></p> <p>出现乱码的原因相信大家都清楚，Tomcat8.5以后的版本已经处理了中文乱码的问题，但是IDEA中的Tomcat插件目前只到Tomcat7，所以需要修改pom.xml来解决GET请求中文乱码问题</p> <div class="language-xml line-numbers-mode"><pre class="language-xml"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>build</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>plugins</span><span class="token punctuation">&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>plugin</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>groupId</span><span class="token punctuation">&gt;</span></span>org.apache.tomcat.maven<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>groupId</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>artifactId</span><span class="token punctuation">&gt;</span></span>tomcat7-maven-plugin<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>artifactId</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>version</span><span class="token punctuation">&gt;</span></span>2.1<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>version</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>configuration</span><span class="token punctuation">&gt;</span></span>
          <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>port</span><span class="token punctuation">&gt;</span></span>80<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>port</span><span class="token punctuation">&gt;</span></span><span class="token comment">&lt;!--tomcat端口号--&gt;</span>
          <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>path</span><span class="token punctuation">&gt;</span></span>/<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>path</span><span class="token punctuation">&gt;</span></span> <span class="token comment">&lt;!--虚拟目录--&gt;</span>
          <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>uriEncoding</span><span class="token punctuation">&gt;</span></span>UTF-8<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>uriEncoding</span><span class="token punctuation">&gt;</span></span><span class="token comment">&lt;!--访问路径编解码字符集--&gt;</span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>configuration</span><span class="token punctuation">&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>plugin</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>plugins</span><span class="token punctuation">&gt;</span></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>build</span><span class="token punctuation">&gt;</span></span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br></div></div><h5 id="post发送参数"><a href="#post发送参数" class="header-anchor">#</a> POST发送参数</h5> <p>发送请求与参数:</p> <p><img src="https://img2023.cnblogs.com/blog/3089561/202302/3089561-20230203225140483-1117038911.png" alt="1630480812809">接收参数：</p> <p>和GET一致，不用做任何修改</p> <div class="language-java line-numbers-mode"><pre class="language-java"><code><span class="token annotation punctuation">@Controller</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">UserController</span> <span class="token punctuation">{</span>

    <span class="token annotation punctuation">@RequestMapping</span><span class="token punctuation">(</span><span class="token string">&quot;/commonParam&quot;</span><span class="token punctuation">)</span>
    <span class="token annotation punctuation">@ResponseBody</span>
    <span class="token keyword">public</span> <span class="token class-name">String</span> <span class="token function">commonParam</span><span class="token punctuation">(</span><span class="token class-name">String</span> name<span class="token punctuation">,</span><span class="token keyword">int</span> age<span class="token punctuation">)</span><span class="token punctuation">{</span>
        <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">&quot;普通参数传递 name ==&gt; &quot;</span><span class="token operator">+</span>name<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">&quot;普通参数传递 age ==&gt; &quot;</span><span class="token operator">+</span>age<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">return</span> <span class="token string">&quot;{'module':'commonParam'}&quot;</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br></div></div><h5 id="post请求中文乱码"><a href="#post请求中文乱码" class="header-anchor">#</a> POST请求中文乱码</h5> <p>发送请求与参数:</p> <p><img src="https://img2023.cnblogs.com/blog/3089561/202302/3089561-20230203225139934-1467695392.png" alt="1630480964421"></p> <p>接收参数:</p> <p>控制台打印，会发现有中文乱码问题。</p> <p><img src="https://img2023.cnblogs.com/blog/3089561/202302/3089561-20230203225139461-533547039.png" alt="1630481008109"></p> <p>解决方案:配置过滤器</p> <div class="language-java line-numbers-mode"><pre class="language-java"><code><span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">ServletContainersInitConfig</span> <span class="token keyword">extends</span> <span class="token class-name">AbstractAnnotationConfigDispatcherServletInitializer</span> <span class="token punctuation">{</span>
    <span class="token keyword">protected</span> <span class="token class-name">Class</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token operator">?</span><span class="token punctuation">&gt;</span></span><span class="token punctuation">[</span><span class="token punctuation">]</span> <span class="token function">getRootConfigClasses</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">Class</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token keyword">protected</span> <span class="token class-name">Class</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token operator">?</span><span class="token punctuation">&gt;</span></span><span class="token punctuation">[</span><span class="token punctuation">]</span> <span class="token function">getServletConfigClasses</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">Class</span><span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">{</span><span class="token class-name">SpringMvcConfig</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">}</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token keyword">protected</span> <span class="token class-name">String</span><span class="token punctuation">[</span><span class="token punctuation">]</span> <span class="token function">getServletMappings</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">String</span><span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">{</span><span class="token string">&quot;/&quot;</span><span class="token punctuation">}</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token comment">//乱码处理</span>
    <span class="token annotation punctuation">@Override</span>
    <span class="token keyword">protected</span> <span class="token class-name">Filter</span><span class="token punctuation">[</span><span class="token punctuation">]</span> <span class="token function">getServletFilters</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token class-name">CharacterEncodingFilter</span> filter <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">CharacterEncodingFilter</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        filter<span class="token punctuation">.</span><span class="token function">setEncoding</span><span class="token punctuation">(</span><span class="token string">&quot;UTF-8&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">Filter</span><span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">{</span>filter<span class="token punctuation">}</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br></div></div><p>CharacterEncodingFilter是在spring-web包中，所以用之前需要导入对应的jar包。</p> <h2 id="_4-3-五种类型参数传递-非json"><a href="#_4-3-五种类型参数传递-非json" class="header-anchor">#</a> 4.3 五种类型参数传递(非json)</h2> <h3 id="而是表单或者地址栏参数"><a href="#而是表单或者地址栏参数" class="header-anchor">#</a> 而是表单或者地址栏参数</h3> <p>前面我们已经能够使用GET或POST来发送请求和数据，所携带的数据都是比较简单的数据，接下来在这个基础上，我们来研究一些比较复杂的参数传递，常见的参数种类有:</p> <ul><li>普通参数</li> <li>POJO类型参数</li> <li>嵌套POJO类型参数</li> <li>数组类型参数</li> <li>集合类型参数</li></ul> <p>这些参数如何发送，后台改如何接收?我们一个个来学习。</p> <h4 id="_4-3-1-普通参数"><a href="#_4-3-1-普通参数" class="header-anchor">#</a> 4.3.1 普通参数</h4> <ul><li>普通参数:url地址传参，地址参数名与形参变量名相同，定义形参即可接收参数。</li></ul> <p><img src="https://img2023.cnblogs.com/blog/3089561/202302/3089561-20230203225138864-1398125311.png" alt="1630481585729"></p> <p>如果形参与地址参数名不一致该如何解决?</p> <p>发送请求与参数:</p> <div class="language- line-numbers-mode"><pre class="language-text"><code>http://localhost/commonParamDifferentName?name=张三&amp;age=18
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br></div></div><p>后台接收参数:</p> <div class="language-java line-numbers-mode"><pre class="language-java"><code><span class="token annotation punctuation">@RequestMapping</span><span class="token punctuation">(</span><span class="token string">&quot;/commonParamDifferentName&quot;</span><span class="token punctuation">)</span>
<span class="token annotation punctuation">@ResponseBody</span>
<span class="token keyword">public</span> <span class="token class-name">String</span> <span class="token function">commonParamDifferentName</span><span class="token punctuation">(</span><span class="token class-name">String</span> userName <span class="token punctuation">,</span> <span class="token keyword">int</span> age<span class="token punctuation">)</span><span class="token punctuation">{</span>
    <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">&quot;普通参数传递 userName ==&gt; &quot;</span><span class="token operator">+</span>userName<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">&quot;普通参数传递 age ==&gt; &quot;</span><span class="token operator">+</span>age<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">return</span> <span class="token string">&quot;{'module':'common param different name'}&quot;</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br></div></div><p>因为前端给的是<code>name</code>,后台接收使用的是<code>userName</code>,两个名称对不上，导致接收数据失败:</p> <p><img src="https://img2023.cnblogs.com/blog/3089561/202302/3089561-20230203225138264-349448555.png" alt="1630481772035"></p> <p>解决方案:使用@RequestParam注解</p> <div class="language-java line-numbers-mode"><pre class="language-java"><code><span class="token annotation punctuation">@RequestMapping</span><span class="token punctuation">(</span><span class="token string">&quot;/commonParamDifferentName&quot;</span><span class="token punctuation">)</span>
    <span class="token annotation punctuation">@ResponseBody</span>
    <span class="token keyword">public</span> <span class="token class-name">String</span> <span class="token function">commonParamDifferentName</span><span class="token punctuation">(</span><span class="token annotation punctuation">@RequestPaam</span><span class="token punctuation">(</span><span class="token string">&quot;name&quot;</span><span class="token punctuation">)</span> <span class="token class-name">String</span> userName <span class="token punctuation">,</span> <span class="token keyword">int</span> age<span class="token punctuation">)</span><span class="token punctuation">{</span>
        <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">&quot;普通参数传递 userName ==&gt; &quot;</span><span class="token operator">+</span>userName<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">&quot;普通参数传递 age ==&gt; &quot;</span><span class="token operator">+</span>age<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">return</span> <span class="token string">&quot;{'module':'common param different name'}&quot;</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br></div></div><p><strong>注意:写上@RequestParam注解框架就不需要自己去解析注入，能提升框架处理性能</strong></p> <h4 id="_4-3-2-pojo数据类型"><a href="#_4-3-2-pojo数据类型" class="header-anchor">#</a> 4.3.2 POJO数据类型</h4> <p>简单数据类型一般处理的是参数个数比较少的请求，如果参数比较多，那么后台接收参数的时候就比较复杂，这个时候我们可以考虑使用POJO数据类型。</p> <ul><li>POJO参数：请求参数名与形参对象属性名相同，定义POJO类型形参即可接收参数</li></ul> <p>此时需要使用前面准备好的POJO类，先来看下User</p> <div class="language-java line-numbers-mode"><pre class="language-java"><code><span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">User</span> <span class="token punctuation">{</span>
    <span class="token keyword">private</span> <span class="token class-name">String</span> name<span class="token punctuation">;</span>
    <span class="token keyword">private</span> <span class="token keyword">int</span> age<span class="token punctuation">;</span>
    <span class="token comment">//setter...getter...略</span>
<span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br></div></div><p>发送请求和参数:</p> <p><img src="https://img2023.cnblogs.com/blog/3089561/202302/3089561-20230203225137685-1249364063.png" alt="1630482186745"></p> <p>后台接收参数:</p> <div class="language-java line-numbers-mode"><pre class="language-java"><code><span class="token comment">//POJO参数：请求参数与形参对象中的属性对应即可完成参数传递</span>
<span class="token annotation punctuation">@RequestMapping</span><span class="token punctuation">(</span><span class="token string">&quot;/pojoParam&quot;</span><span class="token punctuation">)</span>
<span class="token annotation punctuation">@ResponseBody</span>
<span class="token keyword">public</span> <span class="token class-name">String</span> <span class="token function">pojoParam</span><span class="token punctuation">(</span><span class="token class-name">User</span> user<span class="token punctuation">)</span><span class="token punctuation">{</span>
    <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">&quot;pojo参数传递 user ==&gt; &quot;</span><span class="token operator">+</span>user<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">return</span> <span class="token string">&quot;{'module':'pojo param'}&quot;</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br></div></div><p><strong>注意:</strong></p> <ul><li>POJO参数接收，前端GET和POST发送请求数据的方式不变。</li> <li>==请求参数key的名称要和POJO中属性的名称一致，否则无法封装。==</li></ul> <h4 id="_4-3-3-嵌套pojo类型参数"><a href="#_4-3-3-嵌套pojo类型参数" class="header-anchor">#</a> 4.3.3 嵌套POJO类型参数</h4> <p>如果POJO对象中嵌套了其他的POJO类，如</p> <div class="language-java line-numbers-mode"><pre class="language-java"><code><span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">Address</span> <span class="token punctuation">{</span>
    <span class="token keyword">private</span> <span class="token class-name">String</span> province<span class="token punctuation">;</span>
    <span class="token keyword">private</span> <span class="token class-name">String</span> city<span class="token punctuation">;</span>
    <span class="token comment">//setter...getter...略</span>
<span class="token punctuation">}</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">User</span> <span class="token punctuation">{</span>
    <span class="token keyword">private</span> <span class="token class-name">String</span> name<span class="token punctuation">;</span>
    <span class="token keyword">private</span> <span class="token keyword">int</span> age<span class="token punctuation">;</span>
    <span class="token keyword">private</span> <span class="token class-name">Address</span> address<span class="token punctuation">;</span>
    <span class="token comment">//setter...getter...略</span>
<span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br></div></div><ul><li>嵌套POJO参数：请求参数名与形参对象属性名相同，按照对象层次结构关系即可接收嵌套POJO属性参数</li></ul> <p>发送请求和参数:</p> <p><img src="https://img2023.cnblogs.com/blog/3089561/202302/3089561-20230203225137243-1075809834.png" alt="1630482363291"></p> <p>后台接收参数:</p> <div class="language-java line-numbers-mode"><pre class="language-java"><code><span class="token comment">//POJO参数：请求参数与形参对象中的属性对应即可完成参数传递</span>
<span class="token annotation punctuation">@RequestMapping</span><span class="token punctuation">(</span><span class="token string">&quot;/pojoParam&quot;</span><span class="token punctuation">)</span>
<span class="token annotation punctuation">@ResponseBody</span>
<span class="token keyword">public</span> <span class="token class-name">String</span> <span class="token function">pojoParam</span><span class="token punctuation">(</span><span class="token class-name">User</span> user<span class="token punctuation">)</span><span class="token punctuation">{</span>
    <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">&quot;pojo参数传递 user ==&gt; &quot;</span><span class="token operator">+</span>user<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">return</span> <span class="token string">&quot;{'module':'pojo param'}&quot;</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br></div></div><p><strong>注意:</strong></p> <p>==请求参数key的名称要和POJO中属性的名称一致，否则无法封装==</p> <h4 id="_4-3-4-数组类型参数"><a href="#_4-3-4-数组类型参数" class="header-anchor">#</a> 4.3.4 数组类型参数</h4> <p>举个简单的例子，如果前端需要获取用户的爱好，爱好绝大多数情况下都是多个，如何发送请求数据和接收数据呢?</p> <ul><li>数组参数：请求参数名与形参对象属性名相同且请求参数为多个，定义数组类型即可接收参数</li></ul> <p>发送请求和参数:</p> <p><img src="https://img2023.cnblogs.com/blog/3089561/202302/3089561-20230203225136787-2010542649.png" alt="1630482999626"></p> <p>后台接收参数:</p> <div class="language-java line-numbers-mode"><pre class="language-java"><code>  <span class="token comment">//数组参数：同名请求参数可以直接映射到对应名称的形参数组对象中</span>
    <span class="token annotation punctuation">@RequestMapping</span><span class="token punctuation">(</span><span class="token string">&quot;/arrayParam&quot;</span><span class="token punctuation">)</span>
    <span class="token annotation punctuation">@ResponseBody</span>
    <span class="token keyword">public</span> <span class="token class-name">String</span> <span class="token function">arrayParam</span><span class="token punctuation">(</span><span class="token class-name">String</span><span class="token punctuation">[</span><span class="token punctuation">]</span> likes<span class="token punctuation">)</span><span class="token punctuation">{</span>
        <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">&quot;数组参数传递 likes ==&gt; &quot;</span><span class="token operator">+</span> <span class="token class-name">Arrays</span><span class="token punctuation">.</span><span class="token function">toString</span><span class="token punctuation">(</span>likes<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">return</span> <span class="token string">&quot;{'module':'array param'}&quot;</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br></div></div><h4 id="_4-3-5-集合类型参数"><a href="#_4-3-5-集合类型参数" class="header-anchor">#</a> 4.3.5 ==集合类型参数==</h4> <p>数组能接收多个值，那么集合是否也可以实现这个功能呢?</p> <p>发送请求和参数:</p> <p><img src="https://img2023.cnblogs.com/blog/3089561/202302/3089561-20230203225136335-372923214.png" alt="1630484283773"></p> <p>后台接收参数:</p> <div class="language-java line-numbers-mode"><pre class="language-java"><code><span class="token comment">//集合参数：同名请求参数可以使用@RequestParam注解映射到对应名称的集合对象中作为数据</span>
<span class="token annotation punctuation">@RequestMapping</span><span class="token punctuation">(</span><span class="token string">&quot;/listParam&quot;</span><span class="token punctuation">)</span>
<span class="token annotation punctuation">@ResponseBody</span>
<span class="token keyword">public</span> <span class="token class-name">String</span> <span class="token function">listParam</span><span class="token punctuation">(</span><span class="token class-name">List</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">String</span><span class="token punctuation">&gt;</span></span> likes<span class="token punctuation">)</span><span class="token punctuation">{</span>
    <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">&quot;集合参数传递 likes ==&gt; &quot;</span><span class="token operator">+</span> likes<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">return</span> <span class="token string">&quot;{'module':'list param'}&quot;</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br></div></div><p>运行会报错，</p> <p><img src="https://img2023.cnblogs.com/blog/3089561/202302/3089561-20230203225135833-1774857892.png" alt="1630484339065"></p> <p>错误的原因是:SpringMVC将List看做是一个POJO对象来处理，将其创建一个对象并准备把前端的数据封装到对象中，但是List是一个接口无法创建对象，所以报错。</p> <p>解决方案是:使用<code>@RequestParam</code>注解</p> <div class="language-java line-numbers-mode"><pre class="language-java"><code><span class="token comment">//集合参数：同名请求参数可以使用@RequestParam注解映射到对应名称的集合对象中作为数据</span>
<span class="token annotation punctuation">@RequestMapping</span><span class="token punctuation">(</span><span class="token string">&quot;/listParam&quot;</span><span class="token punctuation">)</span>
<span class="token annotation punctuation">@ResponseBody</span>
<span class="token keyword">public</span> <span class="token class-name">String</span> <span class="token function">listParam</span><span class="token punctuation">(</span><span class="token annotation punctuation">@RequestParam</span> <span class="token class-name">List</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">String</span><span class="token punctuation">&gt;</span></span> likes<span class="token punctuation">)</span><span class="token punctuation">{</span>
    <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">&quot;集合参数传递 likes ==&gt; &quot;</span><span class="token operator">+</span> likes<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">return</span> <span class="token string">&quot;{'module':'list param'}&quot;</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br></div></div><ul><li>集合保存普通参数：请求参数名与形参集合对象名相同且请求参数为多个，@RequestParam绑定参数关系</li> <li>对于简单数据类型使用数组会比集合更简单些。</li></ul> <h2 id="_4-4-json数据传输参数"><a href="#_4-4-json数据传输参数" class="header-anchor">#</a> 4.4 JSON数据传输参数</h2> <p>前面我们说过，现在比较流行的开发方式为异步调用。前后台以异步方式进行交换，传输的数据使用的是==JSON==,所以前端如果发送的是JSON数据，后端该如何接收?</p> <p>对于JSON数据类型，我们常见的有三种:</p> <ul><li>json普通数组（[&quot;value1&quot;,&quot;value2&quot;,&quot;value3&quot;,...]）</li> <li>json对象（{key1:value1,key2:value2,...}）</li> <li>json对象数组（[{key1:value1,...},{key2:value2,...}]）</li></ul> <p>对于上述数据，前端如何发送，后端如何接收?</p> <h4 id="json普通数组"><a href="#json普通数组" class="header-anchor">#</a> JSON普通数组</h4> <h6 id="步骤1-pom-xml添加依赖"><a href="#步骤1-pom-xml添加依赖" class="header-anchor">#</a> 步骤1:pom.xml添加依赖</h6> <p>SpringMVC默认使用的是jackson来处理json的转换，所以需要在pom.xml添加jackson依赖</p> <div class="language-xml line-numbers-mode"><pre class="language-xml"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>dependency</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>groupId</span><span class="token punctuation">&gt;</span></span>com.fasterxml.jackson.core<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>groupId</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>artifactId</span><span class="token punctuation">&gt;</span></span>jackson-databind<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>artifactId</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>version</span><span class="token punctuation">&gt;</span></span>2.9.0<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>version</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>dependency</span><span class="token punctuation">&gt;</span></span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br></div></div><h6 id="步骤2-postman发送json数据"><a href="#步骤2-postman发送json数据" class="header-anchor">#</a> 步骤2:PostMan发送JSON数据</h6> <p><img src="https://img2023.cnblogs.com/blog/3089561/202302/3089561-20230203225135073-801378986.png" alt="1630485135061"></p> <h6 id="步骤3-开启springmvc注解支持"><a href="#步骤3-开启springmvc注解支持" class="header-anchor">#</a> 步骤3:开启SpringMVC注解支持</h6> <p>在SpringMVC的配置类中开启SpringMVC的注解支持，这里面就包含了将JSON转换成对象的功能。</p> <div class="language-java line-numbers-mode"><pre class="language-java"><code><span class="token annotation punctuation">@Configuration</span>
<span class="token annotation punctuation">@ComponentScan</span><span class="token punctuation">(</span><span class="token string">&quot;com.itheima.controller&quot;</span><span class="token punctuation">)</span>
<span class="token comment">//开启json数据类型自动转换</span>
<span class="token annotation punctuation">@EnableWebMvc</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">SpringMvcConfig</span> <span class="token punctuation">{</span>
<span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br></div></div><h6 id="步骤4-参数前添加-requestbody"><a href="#步骤4-参数前添加-requestbody" class="header-anchor">#</a> 步骤4:参数前添加@RequestBody</h6> <div class="language-java line-numbers-mode"><pre class="language-java"><code><span class="token comment">//使用@RequestBody注解将外部传递的json数组数据映射到形参的集合对象中作为数据</span>
<span class="token annotation punctuation">@RequestMapping</span><span class="token punctuation">(</span><span class="token string">&quot;/listParamForJson&quot;</span><span class="token punctuation">)</span>
<span class="token annotation punctuation">@ResponseBody</span>
<span class="token keyword">public</span> <span class="token class-name">String</span> <span class="token function">listParamForJson</span><span class="token punctuation">(</span><span class="token annotation punctuation">@RequestBody</span> <span class="token class-name">List</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">String</span><span class="token punctuation">&gt;</span></span> likes<span class="token punctuation">)</span><span class="token punctuation">{</span>
    <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">&quot;list common(json)参数传递 list ==&gt; &quot;</span><span class="token operator">+</span>likes<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">return</span> <span class="token string">&quot;{'module':'list common for json param'}&quot;</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br></div></div><h6 id="步骤5-启动运行程序"><a href="#步骤5-启动运行程序" class="header-anchor">#</a> 步骤5:启动运行程序</h6> <p><img src="https://img2023.cnblogs.com/blog/3089561/202302/3089561-20230203225134578-373914291.png" alt="1630492624684"></p> <p>JSON普通数组的数据就已经传递完成，下面针对JSON对象数据和JSON对象数组的数据该如何传递呢?</p> <h4 id="json对象数据"><a href="#json对象数据" class="header-anchor">#</a> JSON对象数据</h4> <p>我们会发现，只需要关注请求和数据如何发送?后端数据如何接收?</p> <p>请求和数据的发送:</p> <div class="language-json line-numbers-mode"><pre class="language-json"><code><span class="token punctuation">{</span>
	<span class="token property">&quot;name&quot;</span><span class="token operator">:</span><span class="token string">&quot;itcast&quot;</span><span class="token punctuation">,</span>
	<span class="token property">&quot;age&quot;</span><span class="token operator">:</span><span class="token number">15</span>
<span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br></div></div><p><img src="https://img2023.cnblogs.com/blog/3089561/202302/3089561-20230203225134054-2093641676.png" alt="1630493105450"></p> <p>后端接收数据：</p> <div class="language-java line-numbers-mode"><pre class="language-java"><code><span class="token annotation punctuation">@RequestMapping</span><span class="token punctuation">(</span><span class="token string">&quot;/pojoParamForJson&quot;</span><span class="token punctuation">)</span>
<span class="token annotation punctuation">@ResponseBody</span>
<span class="token keyword">public</span> <span class="token class-name">String</span> <span class="token function">pojoParamForJson</span><span class="token punctuation">(</span><span class="token annotation punctuation">@RequestBody</span> <span class="token class-name">User</span> user<span class="token punctuation">)</span><span class="token punctuation">{</span>
    <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">&quot;pojo(json)参数传递 user ==&gt; &quot;</span><span class="token operator">+</span>user<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">return</span> <span class="token string">&quot;{'module':'pojo for json param'}&quot;</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br></div></div><p>启动程序访问测试</p> <p><img src="https://img2023.cnblogs.com/blog/3089561/202302/3089561-20230203225133607-643411899.png" alt="1630493233550"></p> <p><strong>说明:</strong></p> <p>address为null的原因是前端没有传递数据给后端。</p> <p>如果想要address也有数据，我们需求修改前端传递的数据内容:</p> <div class="language-json line-numbers-mode"><pre class="language-json"><code><span class="token punctuation">{</span>
	<span class="token property">&quot;name&quot;</span><span class="token operator">:</span><span class="token string">&quot;itcast&quot;</span><span class="token punctuation">,</span>
	<span class="token property">&quot;age&quot;</span><span class="token operator">:</span><span class="token number">15</span><span class="token punctuation">,</span>
    <span class="token property">&quot;address&quot;</span><span class="token operator">:</span><span class="token punctuation">{</span>
        <span class="token property">&quot;province&quot;</span><span class="token operator">:</span><span class="token string">&quot;beijing&quot;</span><span class="token punctuation">,</span>
        <span class="token property">&quot;city&quot;</span><span class="token operator">:</span><span class="token string">&quot;beijing&quot;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br></div></div><p>再次发送请求，就能看到address中的数据</p> <p><img src="https://img2023.cnblogs.com/blog/3089561/202302/3089561-20230203225133002-1029160777.png" alt="1630493450694"></p> <h4 id="json对象数组"><a href="#json对象数组" class="header-anchor">#</a> JSON对象数组</h4> <p>集合中保存多个POJO该如何实现?</p> <p>请求和数据的发送:</p> <div class="language-json line-numbers-mode"><pre class="language-json"><code><span class="token punctuation">[</span>
    <span class="token punctuation">{</span><span class="token property">&quot;name&quot;</span><span class="token operator">:</span><span class="token string">&quot;itcast&quot;</span><span class="token punctuation">,</span><span class="token property">&quot;age&quot;</span><span class="token operator">:</span><span class="token number">15</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
    <span class="token punctuation">{</span><span class="token property">&quot;name&quot;</span><span class="token operator">:</span><span class="token string">&quot;itheima&quot;</span><span class="token punctuation">,</span><span class="token property">&quot;age&quot;</span><span class="token operator">:</span><span class="token number">12</span><span class="token punctuation">}</span>
<span class="token punctuation">]</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br></div></div><p><img src="https://img2023.cnblogs.com/blog/3089561/202302/3089561-20230203225132469-1600139036.png" alt="1630493501205"></p> <p>后端接收数据:</p> <div class="language-java line-numbers-mode"><pre class="language-java"><code><span class="token annotation punctuation">@RequestMapping</span><span class="token punctuation">(</span><span class="token string">&quot;/listPojoParamForJson&quot;</span><span class="token punctuation">)</span>
<span class="token annotation punctuation">@ResponseBody</span>
<span class="token keyword">public</span> <span class="token class-name">String</span> <span class="token function">listPojoParamForJson</span><span class="token punctuation">(</span><span class="token annotation punctuation">@RequestBody</span> <span class="token class-name">List</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">User</span><span class="token punctuation">&gt;</span></span> list<span class="token punctuation">)</span><span class="token punctuation">{</span>
    <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">&quot;list pojo(json)参数传递 list ==&gt; &quot;</span><span class="token operator">+</span>list<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">return</span> <span class="token string">&quot;{'module':'list pojo for json param'}&quot;</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br></div></div><p>启动程序访问测试</p> <p><img src="https://img2023.cnblogs.com/blog/3089561/202302/3089561-20230203225132006-1832400091.png" alt="1630493561137"></p> <p><strong>小结</strong></p> <p>SpringMVC接收JSON数据的实现步骤为:</p> <p>(1)导入jackson包</p> <p>(2)使用PostMan发送JSON数据</p> <p>(3)开启SpringMVC注解驱动，在配置类上添加@EnableWebMvc注解</p> <p>(4)Controller方法的参数前添加@RequestBody注解</p> <h4 id="知识点1-enablewebmvc"><a href="#知识点1-enablewebmvc" class="header-anchor">#</a> 知识点1：@EnableWebMvc</h4> <table><thead><tr><th>名称</th> <th>@EnableWebMvc</th></tr></thead> <tbody><tr><td>类型</td> <td>==配置类注解==</td></tr> <tr><td>位置</td> <td>SpringMVC配置类定义上方</td></tr> <tr><td>作用</td> <td>开启SpringMVC多项辅助功能</td></tr></tbody></table> <h4 id="知识点2-requestbody"><a href="#知识点2-requestbody" class="header-anchor">#</a> 知识点2：@RequestBody</h4> <table><thead><tr><th>名称</th> <th>@RequestBody</th></tr></thead> <tbody><tr><td>类型</td> <td>==形参注解==</td></tr> <tr><td>位置</td> <td>SpringMVC控制器方法形参定义前面</td></tr> <tr><td>作用</td> <td>将请求中请求体所包含的数据传递给请求参数，此注解一个处理器方法只能使用一次</td></tr></tbody></table> <h4 id="requestbody与-requestparam区别"><a href="#requestbody与-requestparam区别" class="header-anchor">#</a> @RequestBody与@RequestParam区别</h4> <ul><li><p>区别</p> <ul><li>@RequestParam用于接收url地址传参，表单传参【application/x-www-form-urlencoded】</li> <li>@RequestBody用于接收json数据【application/json】</li></ul></li> <li><p>应用</p> <ul><li>后期开发中，发送json格式数据为主，@RequestBody应用较广</li> <li>如果发送非json格式数据，选用@RequestParam接收请求参数</li></ul></li></ul> <h2 id="_4-5-日期类型参数传递"><a href="#_4-5-日期类型参数传递" class="header-anchor">#</a> 4.5 日期类型参数传递</h2> <p>前面我们处理过简单数据类型、POJO数据类型、数组和集合数据类型以及JSON数据类型，接下来我们还得处理一种开发中比较常见的一种数据类型，<code>日期类型</code></p> <p>日期类型比较特殊，因为对于日期的格式有N多中输入方式，比如:</p> <ul><li>2088-08-18</li> <li>2088/08/18</li> <li>08/18/2088</li> <li>......</li></ul> <p>针对这么多日期格式，SpringMVC该如何接收，它能很好的处理日期类型数据么?</p> <h4 id="步骤1-编写方法接收日期数据"><a href="#步骤1-编写方法接收日期数据" class="header-anchor">#</a> 步骤1:编写方法接收日期数据</h4> <p>在UserController类中添加方法，把参数设置为日期类型</p> <div class="language-java line-numbers-mode"><pre class="language-java"><code><span class="token annotation punctuation">@RequestMapping</span><span class="token punctuation">(</span><span class="token string">&quot;/dataParam&quot;</span><span class="token punctuation">)</span>
<span class="token annotation punctuation">@ResponseBody</span>
<span class="token keyword">public</span> <span class="token class-name">String</span> <span class="token function">dataParam</span><span class="token punctuation">(</span><span class="token class-name">Date</span> date<span class="token punctuation">)</span>
    <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">&quot;参数传递 date ==&gt; &quot;</span><span class="token operator">+</span>date<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">return</span> <span class="token string">&quot;{'module':'data param'}&quot;</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br></div></div><h4 id="步骤2-启动tomcat服务器"><a href="#步骤2-启动tomcat服务器" class="header-anchor">#</a> 步骤2:启动Tomcat服务器</h4> <p>查看控制台是否报错，如果有错误，先解决错误。</p> <h4 id="步骤3-使用postman发送请求"><a href="#步骤3-使用postman发送请求" class="header-anchor">#</a> 步骤3:使用PostMan发送请求</h4> <p>使用PostMan发送GET请求，并设置date参数</p> <p><code>http://localhost/dataParam?date=2088/08/08</code></p> <p><img src="https://img2023.cnblogs.com/blog/3089561/202302/3089561-20230203225131365-1683885699.png" alt="1630494320917"></p> <h4 id="步骤4-查看控制台"><a href="#步骤4-查看控制台" class="header-anchor">#</a> 步骤4:查看控制台</h4> <p><img src="https://img2023.cnblogs.com/blog/3089561/202302/3089561-20230203225130868-1350831993.png" alt="1630494443738"></p> <p>通过打印，我们发现SpringMVC可以接收日期数据类型，并将其打印在控制台。</p> <p>这个时候，我们就想如果把日期参数的格式改成其他的，SpringMVC还能处理么?</p> <h4 id="步骤5-更换日期格式"><a href="#步骤5-更换日期格式" class="header-anchor">#</a> 步骤5:更换日期格式</h4> <p>为了能更好的看到程序运行的结果，我们在方法中多添加一个日期参数</p> <div class="language-java line-numbers-mode"><pre class="language-java"><code><span class="token annotation punctuation">@RequestMapping</span><span class="token punctuation">(</span><span class="token string">&quot;/dataParam&quot;</span><span class="token punctuation">)</span>
<span class="token annotation punctuation">@ResponseBody</span>
<span class="token keyword">public</span> <span class="token class-name">String</span> <span class="token function">dataParam</span><span class="token punctuation">(</span><span class="token class-name">Date</span> date<span class="token punctuation">,</span><span class="token class-name">Date</span> date1<span class="token punctuation">)</span>
    <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">&quot;参数传递 date ==&gt; &quot;</span><span class="token operator">+</span>date<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">return</span> <span class="token string">&quot;{'module':'data param'}&quot;</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br></div></div><p>使用PostMan发送请求，携带两个不同的日期格式，</p> <p><code>http://localhost/dataParam?date=2088/08/08&amp;date1=2088-08-08</code></p> <p><img src="https://img2023.cnblogs.com/blog/3089561/202302/3089561-20230203225130106-72212674.png" alt="1630494565970"></p> <p>发送请求和数据后，页面会报400，控制台会报出一个错误</p> <p>Resolved [org.springframework.web.method.annotation.==MethodArgumentTypeMismatchException==: Failed to convert value of type 'java.lang.String' to required type 'java.util.Date'; nested exception is org.springframework.core.convert.==ConversionFailedException==: Failed to convert from type [java.lang.String] to type [java.util.Date] for value '2088-08-08'; nested exception is java.lang.IllegalArgumentException]</p> <p>从错误信息可以看出，错误的原因是在将<code>2088-08-08</code>转换成日期类型的时候失败了，原因是SpringMVC默认支持的字符串转日期的格式为<code>yyyy/MM/dd</code>,而我们现在传递的不符合其默认格式，SpringMVC就无法进行格式转换，所以报错。</p> <p>解决方案也比较简单，需要使用<code>@DateTimeFormat</code></p> <div class="language-java line-numbers-mode"><pre class="language-java"><code><span class="token annotation punctuation">@RequestMapping</span><span class="token punctuation">(</span><span class="token string">&quot;/dataParam&quot;</span><span class="token punctuation">)</span>
<span class="token annotation punctuation">@ResponseBody</span>
<span class="token keyword">public</span> <span class="token class-name">String</span> <span class="token function">dataParam</span><span class="token punctuation">(</span><span class="token class-name">Date</span> date<span class="token punctuation">,</span>
                        <span class="token annotation punctuation">@DateTimeFormat</span><span class="token punctuation">(</span>pattern<span class="token operator">=</span><span class="token string">&quot;yyyy-MM-dd&quot;</span><span class="token punctuation">)</span> <span class="token class-name">Date</span> date1<span class="token punctuation">)</span>
    <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">&quot;参数传递 date ==&gt; &quot;</span><span class="token operator">+</span>date<span class="token punctuation">)</span><span class="token punctuation">;</span>
	<span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">&quot;参数传递 date1(yyyy-MM-dd) ==&gt; &quot;</span><span class="token operator">+</span>date1<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">return</span> <span class="token string">&quot;{'module':'data param'}&quot;</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br></div></div><p>重新启动服务器，重新发送请求测试，SpringMVC就可以正确的进行日期转换了</p> <p><img src="https://img2023.cnblogs.com/blog/3089561/202302/3089561-20230203225129617-1796080909.png" alt="1630495221038"></p> <h4 id="步骤6-携带时间的日期"><a href="#步骤6-携带时间的日期" class="header-anchor">#</a> 步骤6:携带时间的日期</h4> <p>接下来我们再来发送一个携带时间的日期，看下SpringMVC该如何处理?</p> <p>先修改UserController类，添加第三个参数</p> <div class="language-java line-numbers-mode"><pre class="language-java"><code><span class="token annotation punctuation">@RequestMapping</span><span class="token punctuation">(</span><span class="token string">&quot;/dataParam&quot;</span><span class="token punctuation">)</span>
<span class="token annotation punctuation">@ResponseBody</span>
<span class="token keyword">public</span> <span class="token class-name">String</span> <span class="token function">dataParam</span><span class="token punctuation">(</span><span class="token class-name">Date</span> date<span class="token punctuation">,</span>
                        <span class="token annotation punctuation">@DateTimeFormat</span><span class="token punctuation">(</span>pattern<span class="token operator">=</span><span class="token string">&quot;yyyy-MM-dd&quot;</span><span class="token punctuation">)</span> <span class="token class-name">Date</span> date1<span class="token punctuation">,</span>
                        <span class="token annotation punctuation">@DateTimeFormat</span><span class="token punctuation">(</span>pattern<span class="token operator">=</span><span class="token string">&quot;yyyy/MM/dd HH:mm:ss&quot;</span><span class="token punctuation">)</span> <span class="token class-name">Date</span> date2<span class="token punctuation">)</span>
    <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">&quot;参数传递 date ==&gt; &quot;</span><span class="token operator">+</span>date<span class="token punctuation">)</span><span class="token punctuation">;</span>
	<span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">&quot;参数传递 date1(yyyy-MM-dd) ==&gt; &quot;</span><span class="token operator">+</span>date1<span class="token punctuation">)</span><span class="token punctuation">;</span>
	<span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">&quot;参数传递 date2(yyyy/MM/dd HH:mm:ss) ==&gt; &quot;</span><span class="token operator">+</span>date2<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">return</span> <span class="token string">&quot;{'module':'data param'}&quot;</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br></div></div><p>使用PostMan发送请求，携带两个不同的日期格式，</p> <p><code>http://localhost/dataParam?date=2088/08/08&amp;date1=2088-08-08&amp;date2=2088/08/08 8:08:08</code></p> <p><img src="https://img2023.cnblogs.com/blog/3089561/202302/3089561-20230203225128894-826381840.png" alt="1630495347289"></p> <p>重新启动服务器，重新发送请求测试，SpringMVC就可以将日期时间的数据进行转换</p> <p><img src="https://img2023.cnblogs.com/blog/3089561/202302/3089561-20230203225128307-504482069.png" alt="1630495507353"></p> <h4 id="知识点1-datetimeformat"><a href="#知识点1-datetimeformat" class="header-anchor">#</a> 知识点1：@DateTimeFormat</h4> <table><thead><tr><th>名称</th> <th>@DateTimeFormat</th></tr></thead> <tbody><tr><td>类型</td> <td>==形参注解==</td></tr> <tr><td>位置</td> <td>SpringMVC控制器方法形参前面</td></tr> <tr><td>作用</td> <td>设定日期时间型数据格式</td></tr> <tr><td>相关属性</td> <td>pattern：指定日期时间格式字符串</td></tr></tbody></table> <h4 id="内部实现原理"><a href="#内部实现原理" class="header-anchor">#</a> 内部实现原理</h4> <p>讲解内部原理之前，我们需要先思考个问题:</p> <ul><li>前端传递字符串，后端使用日期Date接收</li> <li>前端传递JSON数据，后端使用对象接收</li> <li>前端传递字符串，后端使用Integer接收</li> <li>后台需要的数据类型有很多中</li> <li>在数据的传递过程中存在很多类型的转换</li></ul> <p>问:谁来做这个类型转换?</p> <p>答:SpringMVC</p> <p>问:SpringMVC是如何实现类型转换的?</p> <p>答:SpringMVC中提供了很多类型转换接口和实现类</p> <p>在框架中，有一些类型转换接口，其中有:</p> <ul><li>(1) Converter接口</li></ul> <div class="language-java line-numbers-mode"><pre class="language-java"><code><span class="token comment">/**
*	S: the source type
*	T: the target type
*/</span>
<span class="token keyword">public</span> <span class="token keyword">interface</span> <span class="token class-name">Converter</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">S</span><span class="token punctuation">,</span> <span class="token class-name">T</span><span class="token punctuation">&gt;</span></span> <span class="token punctuation">{</span>
    <span class="token annotation punctuation">@Nullable</span>
    <span class="token comment">//该方法就是将从页面上接收的数据(S)转换成我们想要的数据类型(T)返回</span>
    <span class="token class-name">T</span> <span class="token function">convert</span><span class="token punctuation">(</span><span class="token class-name">S</span> source<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br></div></div><p><strong>注意:Converter所属的包为<code>org.springframework.core.convert.converter</code></strong></p> <p>Converter接口的实现类</p> <p><img src="https://img2023.cnblogs.com/blog/3089561/202302/3089561-20230203225127556-1808039319.png" alt="1630496385398"></p> <p>框架中有提供很多对应Converter接口的实现类，用来实现不同数据类型之间的转换,如:</p> <p>请求参数年龄数据（String→Integer）</p> <p>日期格式转换（String → Date）</p> <ul><li>(2) HttpMessageConverter接口</li></ul> <p>该接口是实现对象与JSON之间的转换工作</p> <p><strong>==注意:SpringMVC的配置类把@EnableWebMvc当做标配配置上去，不要省略==</strong></p> <h2 id="_5-4-3-页面访问处理"><a href="#_5-4-3-页面访问处理" class="header-anchor">#</a> 5.4.3 页面访问处理</h2> <h5 id="步骤1-拷贝静态页面"><a href="#步骤1-拷贝静态页面" class="header-anchor">#</a> 步骤1:拷贝静态页面</h5> <p>将<code>资料\功能页面</code>下的所有内容拷贝到项目的<code>webapp</code>目录下</p> <p><img src="https://img2023.cnblogs.com/blog/3089561/202302/3089561-20230203225127185-1342465758.png" alt="1630510166433"></p> <h5 id="步骤2-访问pages目录下的books-html"><a href="#步骤2-访问pages目录下的books-html" class="header-anchor">#</a> 步骤2:访问pages目录下的books.html</h5> <p>打开浏览器输入<code>http://localhost/pages/books.html</code></p> <p><img src="https://img2023.cnblogs.com/blog/3089561/202302/3089561-20230203225126859-1720734329.png" alt="1630510225182"></p> <p>(1)出现错误的原因?</p> <p><img src="https://img2023.cnblogs.com/blog/3089561/202302/3089561-20230203225126424-2107128536.png" alt="1630510264650"></p> <p>SpringMVC拦截了静态资源，根据/pages/books.html去controller找对应的方法，找不到所以会报404的错误。</p> <p>(2)SpringMVC为什么会拦截静态资源呢?</p> <p><img src="https://img2023.cnblogs.com/blog/3089561/202302/3089561-20230203225125897-728073167.png" alt="1630510397429"></p> <p>(3)解决方案?</p> <ul><li>SpringMVC需要将静态资源进行放行。</li></ul> <div class="language-java line-numbers-mode"><pre class="language-java"><code><span class="token annotation punctuation">@Configuration</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">SpringMvcSupport</span> <span class="token keyword">extends</span> <span class="token class-name">WebMvcConfigurationSupport</span> <span class="token punctuation">{</span>
    <span class="token comment">//设置静态资源访问过滤，当前类需要设置为配置类，并被扫描加载</span>
    <span class="token annotation punctuation">@Override</span>
    <span class="token keyword">protected</span> <span class="token keyword">void</span> <span class="token function">addResourceHandlers</span><span class="token punctuation">(</span><span class="token class-name">ResourceHandlerRegistry</span> registry<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token comment">//当访问/pages/????时候，从/pages目录下查找内容</span>
        registry<span class="token punctuation">.</span><span class="token function">addResourceHandler</span><span class="token punctuation">(</span><span class="token string">&quot;/pages/**&quot;</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">addResourceLocations</span><span class="token punctuation">(</span><span class="token string">&quot;/pages/&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        registry<span class="token punctuation">.</span><span class="token function">addResourceHandler</span><span class="token punctuation">(</span><span class="token string">&quot;/js/**&quot;</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">addResourceLocations</span><span class="token punctuation">(</span><span class="token string">&quot;/js/&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        registry<span class="token punctuation">.</span><span class="token function">addResourceHandler</span><span class="token punctuation">(</span><span class="token string">&quot;/css/**&quot;</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">addResourceLocations</span><span class="token punctuation">(</span><span class="token string">&quot;/css/&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        registry<span class="token punctuation">.</span><span class="token function">addResourceHandler</span><span class="token punctuation">(</span><span class="token string">&quot;/plugins/**&quot;</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">addResourceLocations</span><span class="token punctuation">(</span><span class="token string">&quot;/plugins/&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>

</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br></div></div><ul><li>该配置类是在config目录下，SpringMVC扫描的是controller包，所以该配置类还未生效，要想生效需要将SpringMvcConfig配置类进行修改</li></ul> <div class="language-java line-numbers-mode"><pre class="language-java"><code><span class="token annotation punctuation">@Configuration</span>
<span class="token annotation punctuation">@ComponentScan</span><span class="token punctuation">(</span><span class="token punctuation">{</span><span class="token string">&quot;com.itheima.controller&quot;</span><span class="token punctuation">,</span><span class="token string">&quot;com.itheima.config&quot;</span><span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token annotation punctuation">@EnableWebMvc</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">SpringMvcConfig</span> <span class="token punctuation">{</span>
<span class="token punctuation">}</span>

或者

<span class="token annotation punctuation">@Configuration</span>
<span class="token annotation punctuation">@ComponentScan</span><span class="token punctuation">(</span><span class="token string">&quot;com.itheima&quot;</span><span class="token punctuation">)</span>
<span class="token annotation punctuation">@EnableWebMvc</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">SpringMvcConfig</span> <span class="token punctuation">{</span>
<span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br></div></div><h5 id="步骤3-修改books-html页面"><a href="#步骤3-修改books-html页面" class="header-anchor">#</a> 步骤3:修改books.html页面</h5> <h2 id="springboot-配置文件无提示"><a href="#springboot-配置文件无提示" class="header-anchor">#</a> springboot 配置文件无提示</h2> <p>==注意：在配合文件中如果没有提示，可以使用一下方式解决==</p> <ul><li>点击 <code>File</code> 选中 <code>Project Structure</code></li></ul> <img src="D:/__easyHelper__/ssm的资料/基础框架8笔记/SpringBoot笔记/assets/image-20210917163557071.png" alt="image-20210917163557071" style="zoom:80%;"> <ul><li>弹出如下窗口，按图中标记红框进行选择</li></ul> <img src="D:/__easyHelper__/ssm的资料/基础框架8笔记/SpringBoot笔记/assets/image-20210917163736458.png" alt="image-20210917163736458" style="zoom:70%;"> <ul><li>通过上述操作，会弹出如下窗口</li></ul> <img src="D:/__easyHelper__/ssm的资料/基础框架8笔记/SpringBoot笔记/assets/image-20210917163818051.png" alt="image-20210917163818051" style="zoom:80%;"> <ul><li>点击上图的 <code>+</code> 号，弹出选择该模块的配置文件</li></ul> <img src="D:/__easyHelper__/ssm的资料/基础框架8笔记/SpringBoot笔记/assets/image-20210917163828518.png" alt="image-20210917163828518" style="zoom:80%;"> <ul><li>通过上述几步后，就可以看到如下界面。<code>properties</code> 类型的配合文件有一个，<code>ymal</code> 类型的配置文件有两个</li></ul> <img src="D:/__easyHelper__/ssm的资料/基础框架8笔记/SpringBoot笔记/assets/image-20210917163846243.png" alt="image-20210917163846243" style="zoom:80%;"> <h2 id="springboot-配置文件读取"><a href="#springboot-配置文件读取" class="header-anchor">#</a> springBoot 配置文件读取</h2> <h3 id="_2-3-yaml配置文件数据读取"><a href="#_2-3-yaml配置文件数据读取" class="header-anchor">#</a> 2.3  yaml配置文件数据读取</h3> <h4 id="_2-3-1-环境准备"><a href="#_2-3-1-环境准备" class="header-anchor">#</a> 2.3.1  环境准备</h4> <p>新创建一个名为 <code>springboot_03_read_data</code> 的 <code>SpringBoot</code> 工程，目录结构如下</p> <img src="D:\__easyHelper__\ssm的资料\基础框架8笔记\SpringBoot笔记\assets\image-20210917172736484.png" alt="image-20210917172736484" style="zoom:80%;"> <p>在 <code>com.itheima.controller</code> 包写创建名为 <code>BookController</code> 的控制器，内容如下</p> <div class="language-java line-numbers-mode"><pre class="language-java"><code><span class="token annotation punctuation">@RestController</span>
<span class="token annotation punctuation">@RequestMapping</span><span class="token punctuation">(</span><span class="token string">&quot;/books&quot;</span><span class="token punctuation">)</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">BookController</span> <span class="token punctuation">{</span>

    <span class="token annotation punctuation">@GetMapping</span><span class="token punctuation">(</span><span class="token string">&quot;/{id}&quot;</span><span class="token punctuation">)</span>
    <span class="token keyword">public</span> <span class="token class-name">String</span> <span class="token function">getById</span><span class="token punctuation">(</span><span class="token annotation punctuation">@PathVariable</span> <span class="token class-name">Integer</span> id<span class="token punctuation">)</span><span class="token punctuation">{</span>
        <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">&quot;id ==&gt; &quot;</span><span class="token operator">+</span>id<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">return</span> <span class="token string">&quot;hello , spring boot!&quot;</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br></div></div><p>在 <code>com.itheima.domain</code> 包下创建一个名为 <code>Enterprise</code> 的实体类等会用来封装数据，内容如下</p> <div class="language-java line-numbers-mode"><pre class="language-java"><code><span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">Enterprise</span> <span class="token punctuation">{</span>
    <span class="token keyword">private</span> <span class="token class-name">String</span> name<span class="token punctuation">;</span>
    <span class="token keyword">private</span> <span class="token keyword">int</span> age<span class="token punctuation">;</span>
    <span class="token keyword">private</span> <span class="token class-name">String</span> tel<span class="token punctuation">;</span>
    <span class="token keyword">private</span> <span class="token class-name">String</span><span class="token punctuation">[</span><span class="token punctuation">]</span> subject<span class="token punctuation">;</span>
    
    <span class="token comment">//setter and getter</span>
    
    <span class="token comment">//toString</span>
<span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br></div></div><p>在 <code>resources</code> 下创建一个名为 <code>application.yml</code> 的配置文件，里面配置了不同的数据，内容如下</p> <div class="language-yaml line-numbers-mode"><pre class="language-yaml"><code><span class="token key atrule">lesson</span><span class="token punctuation">:</span> SpringBoot

<span class="token key atrule">server</span><span class="token punctuation">:</span>
  <span class="token key atrule">port</span><span class="token punctuation">:</span> <span class="token number">80</span>

<span class="token key atrule">enterprise</span><span class="token punctuation">:</span>
  <span class="token key atrule">name</span><span class="token punctuation">:</span> itcast
  <span class="token key atrule">age</span><span class="token punctuation">:</span> <span class="token number">16</span>
  <span class="token key atrule">tel</span><span class="token punctuation">:</span> <span class="token number">4006184000</span>
  <span class="token key atrule">subject</span><span class="token punctuation">:</span>
    <span class="token punctuation">-</span> Java
    <span class="token punctuation">-</span> 前端
    <span class="token punctuation">-</span> 大数据
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br></div></div><h4 id="_2-3-2-读取配置数据"><a href="#_2-3-2-读取配置数据" class="header-anchor">#</a> 2.3.2  读取配置数据</h4> <h5 id="_2-3-2-1-使用-value注解"><a href="#_2-3-2-1-使用-value注解" class="header-anchor">#</a> 2.3.2.1  使用 @Value注解</h5> <p>使用 <code>@Value(&quot;表达式&quot;)</code> 注解可以从配合文件中读取数据，注解中用于读取属性名引用方式是：<code>${一级属性名.二级属性名……}</code></p> <p>我们可以在 <code>BookController</code> 中使用 <code>@Value</code>  注解读取配合文件数据，如下</p> <div class="language-java line-numbers-mode"><pre class="language-java"><code><span class="token annotation punctuation">@RestController</span>
<span class="token annotation punctuation">@RequestMapping</span><span class="token punctuation">(</span><span class="token string">&quot;/books&quot;</span><span class="token punctuation">)</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">BookController</span> <span class="token punctuation">{</span>
    
    <span class="token annotation punctuation">@Value</span><span class="token punctuation">(</span><span class="token string">&quot;${lesson}&quot;</span><span class="token punctuation">)</span>
    <span class="token keyword">private</span> <span class="token class-name">String</span> lesson<span class="token punctuation">;</span>
    <span class="token annotation punctuation">@Value</span><span class="token punctuation">(</span><span class="token string">&quot;${server.port}&quot;</span><span class="token punctuation">)</span>
    <span class="token keyword">private</span> <span class="token class-name">Integer</span> port<span class="token punctuation">;</span>
    <span class="token annotation punctuation">@Value</span><span class="token punctuation">(</span><span class="token string">&quot;${enterprise.subject[0]}&quot;</span><span class="token punctuation">)</span>
    <span class="token keyword">private</span> <span class="token class-name">String</span> subject_00<span class="token punctuation">;</span>

    <span class="token annotation punctuation">@GetMapping</span><span class="token punctuation">(</span><span class="token string">&quot;/{id}&quot;</span><span class="token punctuation">)</span>
    <span class="token keyword">public</span> <span class="token class-name">String</span> <span class="token function">getById</span><span class="token punctuation">(</span><span class="token annotation punctuation">@PathVariable</span> <span class="token class-name">Integer</span> id<span class="token punctuation">)</span><span class="token punctuation">{</span>
        <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span>lesson<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span>port<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span>subject_00<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">return</span> <span class="token string">&quot;hello , spring boot!&quot;</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br></div></div><h5 id="_2-3-2-2-environment对象"><a href="#_2-3-2-2-environment对象" class="header-anchor">#</a> 2.3.2.2  Environment对象</h5> <p>上面方式读取到的数据特别零散，<code>SpringBoot</code> 还可以使用 <code>@Autowired</code> 注解注入 <code>Environment</code> 对象的方式读取数据。这种方式 <code>SpringBoot</code> 会将配置文件中所有的数据封装到 <code>Environment</code> 对象中，如果需要使用哪个数据只需要通过调用 <code>Environment</code> 对象的 <code>getProperty(String name)</code> 方法获取。具体代码如下：</p> <div class="language-java line-numbers-mode"><pre class="language-java"><code><span class="token annotation punctuation">@RestController</span>
<span class="token annotation punctuation">@RequestMapping</span><span class="token punctuation">(</span><span class="token string">&quot;/books&quot;</span><span class="token punctuation">)</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">BookController</span> <span class="token punctuation">{</span>
    
    <span class="token annotation punctuation">@Autowired</span>
    <span class="token keyword">private</span> <span class="token class-name">Environment</span> env<span class="token punctuation">;</span>
    
    <span class="token annotation punctuation">@GetMapping</span><span class="token punctuation">(</span><span class="token string">&quot;/{id}&quot;</span><span class="token punctuation">)</span>
    <span class="token keyword">public</span> <span class="token class-name">String</span> <span class="token function">getById</span><span class="token punctuation">(</span><span class="token annotation punctuation">@PathVariable</span> <span class="token class-name">Integer</span> id<span class="token punctuation">)</span><span class="token punctuation">{</span>
        <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span>env<span class="token punctuation">.</span><span class="token function">getProperty</span><span class="token punctuation">(</span><span class="token string">&quot;lesson&quot;</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span>env<span class="token punctuation">.</span><span class="token function">getProperty</span><span class="token punctuation">(</span><span class="token string">&quot;enterprise.name&quot;</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span>env<span class="token punctuation">.</span><span class="token function">getProperty</span><span class="token punctuation">(</span><span class="token string">&quot;enterprise.subject[0]&quot;</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">return</span> <span class="token string">&quot;hello , spring boot!&quot;</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br></div></div><blockquote><p>==注意：这种方式，框架内容大量数据，而在开发中我们很少使用。==</p></blockquote> <h5 id="_2-3-2-3-自定义对象"><a href="#_2-3-2-3-自定义对象" class="header-anchor">#</a> 2.3.2.3  自定义对象</h5> <p><code>SpringBoot</code> 还提供了将配置文件中的数据封装到我们自定义的实体类对象中的方式。具体操作如下：</p> <ul><li><p>将实体类 <code>bean</code> 的创建交给 <code>Spring</code> 管理。</p> <p>在类上添加 <code>@Component</code> 注解</p></li> <li><p>使用 <code>@ConfigurationProperties</code> 注解表示加载配置文件</p> <p>在该注解中也可以使用 <code>prefix</code> 属性指定只加载指定前缀的数据</p></li> <li><p>在 <code>BookController</code> 中进行注入</p></li></ul> <p><strong>具体代码如下：</strong></p> <p><code>Enterprise</code> 实体类内容如下：</p> <div class="language-java line-numbers-mode"><pre class="language-java"><code><span class="token annotation punctuation">@Component</span>
<span class="token annotation punctuation">@ConfigurationProperties</span><span class="token punctuation">(</span>prefix <span class="token operator">=</span> <span class="token string">&quot;enterprise&quot;</span><span class="token punctuation">)</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">Enterprise</span> <span class="token punctuation">{</span>
    <span class="token keyword">private</span> <span class="token class-name">String</span> name<span class="token punctuation">;</span>
    <span class="token keyword">private</span> <span class="token keyword">int</span> age<span class="token punctuation">;</span>
    <span class="token keyword">private</span> <span class="token class-name">String</span> tel<span class="token punctuation">;</span>
    <span class="token keyword">private</span> <span class="token class-name">String</span><span class="token punctuation">[</span><span class="token punctuation">]</span> subject<span class="token punctuation">;</span>

    <span class="token keyword">public</span> <span class="token class-name">String</span> <span class="token function">getName</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">return</span> name<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setName</span><span class="token punctuation">(</span><span class="token class-name">String</span> name<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span>name <span class="token operator">=</span> name<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token keyword">public</span> <span class="token keyword">int</span> <span class="token function">getAge</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">return</span> age<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setAge</span><span class="token punctuation">(</span><span class="token keyword">int</span> age<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span>age <span class="token operator">=</span> age<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token keyword">public</span> <span class="token class-name">String</span> <span class="token function">getTel</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">return</span> tel<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setTel</span><span class="token punctuation">(</span><span class="token class-name">String</span> tel<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span>tel <span class="token operator">=</span> tel<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token keyword">public</span> <span class="token class-name">String</span><span class="token punctuation">[</span><span class="token punctuation">]</span> <span class="token function">getSubject</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">return</span> subject<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setSubject</span><span class="token punctuation">(</span><span class="token class-name">String</span><span class="token punctuation">[</span><span class="token punctuation">]</span> subject<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span>subject <span class="token operator">=</span> subject<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token annotation punctuation">@Override</span>
    <span class="token keyword">public</span> <span class="token class-name">String</span> <span class="token function">toString</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">return</span> <span class="token string">&quot;Enterprise{&quot;</span> <span class="token operator">+</span>
                <span class="token string">&quot;name='&quot;</span> <span class="token operator">+</span> name <span class="token operator">+</span> <span class="token char">'\''</span> <span class="token operator">+</span>
                <span class="token string">&quot;, age=&quot;</span> <span class="token operator">+</span> age <span class="token operator">+</span>
                <span class="token string">&quot;, tel='&quot;</span> <span class="token operator">+</span> tel <span class="token operator">+</span> <span class="token char">'\''</span> <span class="token operator">+</span>
                <span class="token string">&quot;, subject=&quot;</span> <span class="token operator">+</span> <span class="token class-name">Arrays</span><span class="token punctuation">.</span><span class="token function">toString</span><span class="token punctuation">(</span>subject<span class="token punctuation">)</span> <span class="token operator">+</span>
                <span class="token char">'}'</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br><span class="line-number">27</span><br><span class="line-number">28</span><br><span class="line-number">29</span><br><span class="line-number">30</span><br><span class="line-number">31</span><br><span class="line-number">32</span><br><span class="line-number">33</span><br><span class="line-number">34</span><br><span class="line-number">35</span><br><span class="line-number">36</span><br><span class="line-number">37</span><br><span class="line-number">38</span><br><span class="line-number">39</span><br><span class="line-number">40</span><br><span class="line-number">41</span><br><span class="line-number">42</span><br><span class="line-number">43</span><br><span class="line-number">44</span><br><span class="line-number">45</span><br><span class="line-number">46</span><br><span class="line-number">47</span><br><span class="line-number">48</span><br><span class="line-number">49</span><br><span class="line-number">50</span><br></div></div><p><code>BookController</code> 内容如下：</p> <div class="language-java line-numbers-mode"><pre class="language-java"><code><span class="token annotation punctuation">@RestController</span>
<span class="token annotation punctuation">@RequestMapping</span><span class="token punctuation">(</span><span class="token string">&quot;/books&quot;</span><span class="token punctuation">)</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">BookController</span> <span class="token punctuation">{</span>
    
    <span class="token annotation punctuation">@Autowired</span>
    <span class="token keyword">private</span> <span class="token class-name">Enterprise</span> enterprise<span class="token punctuation">;</span>

    <span class="token annotation punctuation">@GetMapping</span><span class="token punctuation">(</span><span class="token string">&quot;/{id}&quot;</span><span class="token punctuation">)</span>
    <span class="token keyword">public</span> <span class="token class-name">String</span> <span class="token function">getById</span><span class="token punctuation">(</span><span class="token annotation punctuation">@PathVariable</span> <span class="token class-name">Integer</span> id<span class="token punctuation">)</span><span class="token punctuation">{</span>
        <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span>enterprise<span class="token punctuation">.</span><span class="token function">getName</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span>enterprise<span class="token punctuation">.</span><span class="token function">getAge</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span>enterprise<span class="token punctuation">.</span><span class="token function">getSubject</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span>enterprise<span class="token punctuation">.</span><span class="token function">getTel</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span>enterprise<span class="token punctuation">.</span><span class="token function">getSubject</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">return</span> <span class="token string">&quot;hello , spring boot!&quot;</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br></div></div><p>==注意：==</p> <p>使用第三种方式，在实体类上有如下警告提示</p> <img src="D:\__easyHelper__\ssm的资料\基础框架8笔记\SpringBoot笔记\assets\image-20210917180919390.png" alt="image-20210917180919390" style="zoom:70%;"> <p>这个警告提示解决是在 <code>pom.xml</code> 中添加如下依赖即可</p> <div class="language-xml line-numbers-mode"><pre class="language-xml"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>dependency</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>groupId</span><span class="token punctuation">&gt;</span></span>org.springframework.boot<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>groupId</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>artifactId</span><span class="token punctuation">&gt;</span></span>spring-boot-configuration-processor<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>artifactId</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>optional</span><span class="token punctuation">&gt;</span></span>true<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>optional</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>dependency</span><span class="token punctuation">&gt;</span></span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br></div></div><h3 id="_2-4-多环境配置"><a href="#_2-4-多环境配置" class="header-anchor">#</a> 2.4  多环境配置</h3> <p>以后在工作中，对于开发环境、测试环境、生产环境的配置肯定都不相同，比如我们开发阶段会在自己的电脑上安装 <code>mysql</code> ，连接自己电脑上的 <code>mysql</code> 即可，但是项目开发完毕后要上线就需要该配置，将环境的配置改为线上环境的。</p> <img src="D:\__easyHelper__\ssm的资料\基础框架8笔记\SpringBoot笔记\assets\image-20210917185253557.png" alt="image-20210917185253557" style="zoom:60%;"> <p>来回的修改配置会很麻烦，而 <code>SpringBoot</code> 给开发者提供了多环境的快捷配置，需要切换环境时只需要改一个配置即可。不同类型的配置文件多环境开发的配置都不相同，接下来对不同类型的配置文件进行说明</p> <h4 id="_2-4-1-yaml文件"><a href="#_2-4-1-yaml文件" class="header-anchor">#</a> 2.4.1  yaml文件</h4> <p>在 <code>application.yml</code> 中使用 <code>---</code> 来分割不同的配置，内容如下</p> <div class="language-yaml line-numbers-mode"><pre class="language-yaml"><code><span class="token comment">#开发</span>
<span class="token key atrule">spring</span><span class="token punctuation">:</span>
  <span class="token key atrule">profiles</span><span class="token punctuation">:</span> dev <span class="token comment">#给开发环境起的名字</span>
<span class="token key atrule">server</span><span class="token punctuation">:</span>
  <span class="token key atrule">port</span><span class="token punctuation">:</span> <span class="token number">80</span>
<span class="token punctuation">---</span>
<span class="token comment">#生产</span>
<span class="token key atrule">spring</span><span class="token punctuation">:</span>
  <span class="token key atrule">profiles</span><span class="token punctuation">:</span> pro <span class="token comment">#给生产环境起的名字</span>
<span class="token key atrule">server</span><span class="token punctuation">:</span>
  <span class="token key atrule">port</span><span class="token punctuation">:</span> <span class="token number">81</span>
<span class="token punctuation">---</span>
<span class="token comment">#测试</span>
<span class="token key atrule">spring</span><span class="token punctuation">:</span>
  <span class="token key atrule">profiles</span><span class="token punctuation">:</span> test <span class="token comment">#给测试环境起的名字</span>
<span class="token key atrule">server</span><span class="token punctuation">:</span>
  <span class="token key atrule">port</span><span class="token punctuation">:</span> <span class="token number">82</span>
<span class="token punctuation">---</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br></div></div><p>上面配置中 <code>spring.profiles</code> 是用来给不同的配置起名字的。而如何告知 <code>SpringBoot</code> 使用哪段配置呢？可以使用如下配置来启用都一段配置</p> <div class="language-yaml line-numbers-mode"><pre class="language-yaml"><code><span class="token comment">#设置启用的环境</span>
<span class="token key atrule">spring</span><span class="token punctuation">:</span>
  <span class="token key atrule">profiles</span><span class="token punctuation">:</span>
    <span class="token key atrule">active</span><span class="token punctuation">:</span> dev  <span class="token comment">#表示使用的是开发环境的配置</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br></div></div><p>综上所述，<code>application.yml</code> 配置文件内容如下</p> <div class="language-yaml line-numbers-mode"><pre class="language-yaml"><code><span class="token comment">#设置启用的环境</span>
<span class="token key atrule">spring</span><span class="token punctuation">:</span>
  <span class="token key atrule">profiles</span><span class="token punctuation">:</span>
    <span class="token key atrule">active</span><span class="token punctuation">:</span> dev

<span class="token punctuation">---</span>
<span class="token comment">#开发</span>
<span class="token key atrule">spring</span><span class="token punctuation">:</span>
  <span class="token key atrule">profiles</span><span class="token punctuation">:</span> dev
<span class="token key atrule">server</span><span class="token punctuation">:</span>
  <span class="token key atrule">port</span><span class="token punctuation">:</span> <span class="token number">80</span>
<span class="token punctuation">---</span>
<span class="token comment">#生产</span>
<span class="token key atrule">spring</span><span class="token punctuation">:</span>
  <span class="token key atrule">profiles</span><span class="token punctuation">:</span> pro
<span class="token key atrule">server</span><span class="token punctuation">:</span>
  <span class="token key atrule">port</span><span class="token punctuation">:</span> <span class="token number">81</span>
<span class="token punctuation">---</span>
<span class="token comment">#测试</span>
<span class="token key atrule">spring</span><span class="token punctuation">:</span>
  <span class="token key atrule">profiles</span><span class="token punctuation">:</span> test
<span class="token key atrule">server</span><span class="token punctuation">:</span>
  <span class="token key atrule">port</span><span class="token punctuation">:</span> <span class="token number">82</span>
<span class="token punctuation">---</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br></div></div><p>==注意：==</p> <p>在上面配置中给不同配置起名字的 <code>spring.profiles</code> 配置项已经过时。最新用来起名字的配置项是</p> <div class="language-yaml line-numbers-mode"><pre class="language-yaml"><code><span class="token comment">#开发</span>
<span class="token key atrule">spring</span><span class="token punctuation">:</span>
  <span class="token key atrule">config</span><span class="token punctuation">:</span>
    <span class="token key atrule">activate</span><span class="token punctuation">:</span>
      <span class="token key atrule">on-profile</span><span class="token punctuation">:</span> dev
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br></div></div><h4 id="_2-4-2-properties文件"><a href="#_2-4-2-properties文件" class="header-anchor">#</a> 2.4.2  properties文件</h4> <p><code>properties</code> 类型的配置文件配置多环境需要定义不同的配置文件</p> <ul><li><p><code>application-dev.properties</code> 是开发环境的配置文件。我们在该文件中配置端口号为 <code>80</code></p> <div class="language-properties line-numbers-mode"><pre class="language-properties"><code><span class="token key attr-name">server.port</span><span class="token punctuation">=</span><span class="token value attr-value">80</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br></div></div></li> <li><p><code>application-test.properties</code> 是测试环境的配置文件。我们在该文件中配置端口号为 <code>81</code></p> <div class="language-properties line-numbers-mode"><pre class="language-properties"><code><span class="token key attr-name">server.port</span><span class="token punctuation">=</span><span class="token value attr-value">81</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br></div></div></li> <li><p><code>application-pro.properties</code> 是生产环境的配置文件。我们在该文件中配置端口号为 <code>82</code></p> <div class="language-properties line-numbers-mode"><pre class="language-properties"><code><span class="token key attr-name">server.port</span><span class="token punctuation">=</span><span class="token value attr-value">82</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br></div></div></li></ul> <p><code>SpringBoot</code> 只会默认加载名为 <code>application.properties</code> 的配置文件，所以需要在 <code>application.properties</code> 配置文件中设置启用哪个配置文件，配置如下:</p> <div class="language-properties line-numbers-mode"><pre class="language-properties"><code><span class="token key attr-name">spring.profiles.active</span><span class="token punctuation">=</span><span class="token value attr-value">pro</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br></div></div><h4 id="_2-4-3-命令行启动参数设置"><a href="#_2-4-3-命令行启动参数设置" class="header-anchor">#</a> 2.4.3  命令行启动参数设置</h4> <p>使用 <code>SpringBoot</code> 开发的程序以后都是打成 <code>jar</code> 包，通过 <code>java -jar xxx.jar</code> 的方式启动服务的。那么就存在一个问题，如何切换环境呢？因为配置文件打到的jar包中了。</p> <p>我们知道 <code>jar</code> 包其实就是一个压缩包，可以解压缩，然后修改配置，最后再打成jar包就可以了。这种方式显然有点麻烦，而 <code>SpringBoot</code> 提供了在运行 <code>jar</code> 时设置开启指定的环境的方式，如下</p> <div class="language-shell line-numbers-mode"><pre class="language-shell"><code><span class="token function">java</span> –jar xxx.jar –-spring.profiles.active<span class="token operator">=</span>test
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br></div></div><p>那么这种方式能不能临时修改端口号呢？也是可以的，可以通过如下方式</p> <div class="language-shell line-numbers-mode"><pre class="language-shell"><code><span class="token function">java</span> –jar xxx.jar –-server.port<span class="token operator">=</span><span class="token number">88</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br></div></div><p>当然也可以同时设置多个配置，比如即指定启用哪个环境配置，又临时指定端口，如下</p> <div class="language-shell line-numbers-mode"><pre class="language-shell"><code><span class="token function">java</span> –jar springboot.jar –-server.port<span class="token operator">=</span><span class="token number">88</span> –-spring.profiles.active<span class="token operator">=</span>test
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br></div></div><p>大家进行测试后就会发现命令行设置的端口号优先级高（也就是使用的是命令行设置的端口号），配置的优先级其实 <code>SpringBoot</code> 官网已经进行了说明，参见 :</p> <div class="language- line-numbers-mode"><pre class="language-text"><code>https://docs.spring.io/spring-boot/docs/current/reference/html/spring-boot-features.html#boot-features-external-config
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br></div></div><p>进入上面网站后会看到如下页面</p> <p><img src="https://img2023.cnblogs.com/blog/3089561/202302/3089561-20230203225125443-747684614.png" alt="image-20210917193910191"></p> <p>如果使用了多种方式配合同一个配置项，优先级高的生效。</p> <h3 id="_2-5-配置文件分类"><a href="#_2-5-配置文件分类" class="header-anchor">#</a> 2.5  配置文件分类</h3> <img src="D:\__easyHelper__\ssm的资料\基础框架8笔记\SpringBoot笔记\assets\image-20210917194941597.png" alt="image-20210917194941597" style="zoom:70%;"> <p>有这样的场景，我们开发完毕后需要测试人员进行测试，由于测试环境和开发环境的很多配置都不相同，所以测试人员在运行我们的工程时需要临时修改很多配置，如下</p> <div class="language-shell line-numbers-mode"><pre class="language-shell"><code><span class="token function">java</span> –jar springboot.jar –-spring.profiles.active<span class="token operator">=</span>test <span class="token parameter variable">--server.port</span><span class="token operator">=</span><span class="token number">85</span> --server.servlet.context-path<span class="token operator">=</span>/heima --server.tomcat.connection-timeout<span class="token operator">=</span>-1 …… …… …… …… ……
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br></div></div><p>针对这种情况，<code>SpringBoot</code> 定义了配置文件不同的放置的位置；而放在不同位置的优先级时不同的。</p> <p><code>SpringBoot</code> 中4级配置文件放置位置：</p> <ul><li>1级：classpath：application.yml</li> <li>2级：classpath：config/application.yml</li> <li>3级：file ：application.yml</li> <li>4级：file ：config/application.yml</li></ul> <blockquote><p>==说明：==级别越高优先级越高</p></blockquote> <h4 id="_2-5-1-代码演示"><a href="#_2-5-1-代码演示" class="header-anchor">#</a> 2.5.1  代码演示</h4> <p>在这里我们只演示不同级别配置文件放置位置的优先级。</p> <h5 id="_2-5-1-1-环境准备"><a href="#_2-5-1-1-环境准备" class="header-anchor">#</a> 2.5.1.1  环境准备</h5> <p>创建一个名为 <code>springboot_06_config_file</code> 的 <code>SpringBoot</code> 工程，目录结构如下</p> <img src="D:\__easyHelper__\ssm的资料\基础框架8笔记\SpringBoot笔记\assets\image-20210917200241282.png" alt="image-20210917200241282" style="zoom:80%;"> <p>在 <code>resources</code> 下创建一个名为 <code>config</code> 的目录，在该目录中创建 <code>application.yml</code> 配置文件，而在该配置文件中将端口号设置为 <code>81</code>，内容如下</p> <div class="language-yaml line-numbers-mode"><pre class="language-yaml"><code><span class="token key atrule">server</span><span class="token punctuation">:</span>
  <span class="token key atrule">port</span><span class="token punctuation">:</span> <span class="token number">81</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br></div></div><p>而在 <code>resources</code> 下创建的 <code>application.yml</code> 配置文件中并将端口号设置为 <code>80</code>，内容如下</p> <div class="language-yaml line-numbers-mode"><pre class="language-yaml"><code><span class="token key atrule">server</span><span class="token punctuation">:</span>
  <span class="token key atrule">port</span><span class="token punctuation">:</span> <span class="token number">80</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br></div></div><h5 id="_2-5-1-2-验证1级和2级的优先级"><a href="#_2-5-1-2-验证1级和2级的优先级" class="header-anchor">#</a> 2.5.1.2  验证1级和2级的优先级</h5> <p>运行启动引导类，可以在控制台看到如下日志信息</p> <p><img src="https://img2023.cnblogs.com/blog/3089561/202302/3089561-20230203225124934-1112231887.png" alt="image-20210917200805389"></p> <p>通过这个结果可以得出==类路径下的 <code>config</code> 下的配置文件优先于类路径下的配置文件。==</p> <h5 id="_2-5-1-3-验证2级和4级的优先级"><a href="#_2-5-1-3-验证2级和4级的优先级" class="header-anchor">#</a> 2.5.1.3  验证2级和4级的优先级</h5> <p>要验证4级，按照以下步骤完成</p> <ul><li><p>将工程打成 <code>jar</code> 包</p> <p>点击工程的 <code>package</code> 来打 <code>jar</code> 包</p> <img src="D:\__easyHelper__\ssm的资料\基础框架8笔记\SpringBoot笔记\assets\image-20210917201243721.png" alt="image-20210917201243721" style="zoom:80%;"></li> <li><p>在硬盘上找到 <code>jar</code> 包所在位置</p> <img src="D:\__easyHelper__\ssm的资料\基础框架8笔记\SpringBoot笔记\assets\image-20210917201523669.png" alt="image-20210917201523669" style="zoom:70%;"></li> <li><p>在 <code>jar</code> 包所在位置创建 <code>config</code> 文件夹，在该文件夹下创建 <code>application.yml</code> 配置文件，而在该配合文件中将端口号设置为 <code>82</code></p></li> <li><p>在命令行使用以下命令运行程序</p> <div class="language-shell line-numbers-mode"><pre class="language-shell"><code><span class="token function">java</span> <span class="token parameter variable">-jar</span> springboot_06_config_file-0.0.1-SNAPSHOT.jar
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br></div></div><p>运行后日志信息如下</p> <p><img src="https://img2023.cnblogs.com/blog/3089561/202302/3089561-20230203225124546-1126608228.png" alt="image-20210917201922831"></p> <p>通过这个结果可以得出==file： <code>config</code> 下的配置文件优先于类路径下的配置文件。==</p></li></ul> <blockquote><p>==注意：==</p> <p>SpringBoot 2.5.0版本存在一个bug，我们在使用这个版本时，需要在 <code>jar</code> 所在位置的 <code>config</code> 目录下创建一个任意名称的文件夹</p></blockquote> <h2 id="mybatis-plus-使用时的特殊情况"><a href="#mybatis-plus-使用时的特殊情况" class="header-anchor">#</a> mybatis-plus 使用时的特殊情况</h2> <h3 id="_3-4-映射匹配兼容性"><a href="#_3-4-映射匹配兼容性" class="header-anchor">#</a> 3.4 映射匹配兼容性</h3> <p>前面我们已经能从表中查询出数据，并将数据封装到模型类中，这整个过程涉及到一张表和一个模型类:</p> <p><img src="https://img2023.cnblogs.com/blog/3089561/202302/3089561-20230203225124051-1950242518.png" alt="1631030296965"></p> <p>之所以数据能够成功的从表中获取并封装到模型对象中，原因是表的字段列名和模型类的属性名一样。</p> <p>那么问题就来了:</p> <h4 id="问题1-表字段与编码属性设计不同步"><a href="#问题1-表字段与编码属性设计不同步" class="header-anchor">#</a> 问题1:表字段与编码属性设计不同步</h4> <p>当表的列名和模型类的属性名发生不一致，就会导致数据封装不到模型对象，这个时候就需要其中一方做出修改，那如果前提是两边都不能改又该如何解决?</p> <p>MP给我们提供了一个注解<code>@TableField</code>,使用该注解可以实现模型类属性名和表的列名之间的映射关系</p> <p><img src="https://img2023.cnblogs.com/blog/3089561/202302/3089561-20230203225123529-2074716236.png" alt="1631030550100"></p> <h4 id="问题2-编码中添加了数据库中未定义的属性"><a href="#问题2-编码中添加了数据库中未定义的属性" class="header-anchor">#</a> 问题2:编码中添加了数据库中未定义的属性</h4> <p>当模型类中多了一个数据库表不存在的字段，就会导致生成的sql语句中在select的时候查询了数据库不存在的字段，程序运行就会报错，错误信息为:</p> <p>==Unknown column '多出来的字段名称' in 'field list'==</p> <p>具体的解决方案用到的还是<code>@TableField</code>注解，它有一个属性叫<code>exist</code>，设置该字段是否在数据库表中存在，如果设置为false则不存在，生成sql语句查询的时候，就不会再查询该字段了。</p> <p><img src="https://img2023.cnblogs.com/blog/3089561/202302/3089561-20230203225122976-182434243.png" alt="1631031054206"></p> <h4 id="问题3-采用默认查询开放了更多的字段查看权限"><a href="#问题3-采用默认查询开放了更多的字段查看权限" class="header-anchor">#</a> 问题3：采用默认查询开放了更多的字段查看权限</h4> <p>查询表中所有的列的数据，就可能把一些敏感数据查询到返回给前端，这个时候我们就需要限制哪些字段默认不要进行查询。解决方案是<code>@TableField</code>注解的一个属性叫<code>select</code>，该属性设置默认是否需要查询该字段的值，true(默认值)表示默认查询该字段，false表示默认不查询该字段。</p> <p><img src="https://img2023.cnblogs.com/blog/3089561/202302/3089561-20230203225122526-738848027.png" alt="1631031270558"></p> <h4 id="知识点1-tablefield"><a href="#知识点1-tablefield" class="header-anchor">#</a> 知识点1：@TableField</h4> <table><thead><tr><th>名称</th> <th>@TableField</th></tr></thead> <tbody><tr><td>类型</td> <td>==属性注解==</td></tr> <tr><td>位置</td> <td>模型类属性定义上方</td></tr> <tr><td>作用</td> <td>设置当前属性对应的数据库表中的字段关系</td></tr> <tr><td>相关属性</td> <td>value(默认)：设置数据库表字段名称<br>exist:设置属性在数据库表字段中是否存在，默认为true，此属性不能与value合并使用<br>select:设置属性是否参与查询，此属性与select()映射配置不冲突</td></tr></tbody></table> <h4 id="问题4-表名与编码开发设计不同步"><a href="#问题4-表名与编码开发设计不同步" class="header-anchor">#</a> 问题4:表名与编码开发设计不同步</h4> <p>该问题主要是表的名称和模型类的名称不一致，导致查询失败，这个时候通常会报如下错误信息:</p> <p>==Table 'databaseName.tableNaem' doesn't exist==,翻译过来就是数据库中的表不存在。</p> <p><img src="https://img2023.cnblogs.com/blog/3089561/202302/3089561-20230203225121829-69302454.png" alt="1631031828378"></p> <p>解决方案是使用MP提供的另外一个注解<code>@TableName</code>来设置表与模型类之间的对应关系。</p> <p><img src="https://img2023.cnblogs.com/blog/3089561/202302/3089561-20230203225121228-1880105959.png" alt="1631031915632"></p> <h4 id="知识点2-tablename"><a href="#知识点2-tablename" class="header-anchor">#</a> 知识点2：@TableName</h4> <table><thead><tr><th>名称</th> <th>@TableName</th></tr></thead> <tbody><tr><td>类型</td> <td>==类注解==</td></tr> <tr><td>位置</td> <td>模型类定义上方</td></tr> <tr><td>作用</td> <td>设置当前类对应于数据库表关系</td></tr> <tr><td>相关属性</td> <td>value(默认)：设置数据库表名称</td></tr></tbody></table> <h4 id="代码演示"><a href="#代码演示" class="header-anchor">#</a> 代码演示</h4> <p>接下来我们使用案例的方式把刚才的知识演示下:</p> <h5 id="步骤1-修改数据库表user为tbl-user"><a href="#步骤1-修改数据库表user为tbl-user" class="header-anchor">#</a> 步骤1:修改数据库表user为tbl_user</h5> <p>直接查询会报错，原因是MP默认情况下会使用模型类的类名首字母小写当表名使用。</p> <p><img src="https://img2023.cnblogs.com/blog/3089561/202302/3089561-20230203225120499-1215026710.png" alt="1631032123894"></p> <h5 id="步骤2-模型类添加-tablename注解"><a href="#步骤2-模型类添加-tablename注解" class="header-anchor">#</a> 步骤2:模型类添加@TableName注解</h5> <div class="language-java line-numbers-mode"><pre class="language-java"><code><span class="token annotation punctuation">@Data</span>
<span class="token annotation punctuation">@TableName</span><span class="token punctuation">(</span><span class="token string">&quot;tbl_user&quot;</span><span class="token punctuation">)</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">User</span> <span class="token punctuation">{</span>
    <span class="token keyword">private</span> <span class="token class-name">Long</span> id<span class="token punctuation">;</span>
    <span class="token keyword">private</span> <span class="token class-name">String</span> name<span class="token punctuation">;</span>
    <span class="token keyword">private</span> <span class="token class-name">String</span> password<span class="token punctuation">;</span>
    <span class="token keyword">private</span> <span class="token class-name">Integer</span> age<span class="token punctuation">;</span>
    <span class="token keyword">private</span> <span class="token class-name">String</span> tel<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br></div></div><h5 id="步骤3-将字段password修改成pwd"><a href="#步骤3-将字段password修改成pwd" class="header-anchor">#</a> 步骤3:将字段password修改成pwd</h5> <p>直接查询会报错，原因是MP默认情况下会使用模型类的属性名当做表的列名使用</p> <p><img src="https://img2023.cnblogs.com/blog/3089561/202302/3089561-20230203225119805-558781297.png" alt="1631032283147"></p> <h5 id="步骤4-使用-tablefield映射关系"><a href="#步骤4-使用-tablefield映射关系" class="header-anchor">#</a> 步骤4：使用@TableField映射关系</h5> <div class="language-java line-numbers-mode"><pre class="language-java"><code><span class="token annotation punctuation">@Data</span>
<span class="token annotation punctuation">@TableName</span><span class="token punctuation">(</span><span class="token string">&quot;tbl_user&quot;</span><span class="token punctuation">)</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">User</span> <span class="token punctuation">{</span>
    <span class="token keyword">private</span> <span class="token class-name">Long</span> id<span class="token punctuation">;</span>
    <span class="token keyword">private</span> <span class="token class-name">String</span> name<span class="token punctuation">;</span>
    <span class="token annotation punctuation">@TableField</span><span class="token punctuation">(</span>value<span class="token operator">=</span><span class="token string">&quot;pwd&quot;</span><span class="token punctuation">)</span>
    <span class="token keyword">private</span> <span class="token class-name">String</span> password<span class="token punctuation">;</span>
    <span class="token keyword">private</span> <span class="token class-name">Integer</span> age<span class="token punctuation">;</span>
    <span class="token keyword">private</span> <span class="token class-name">String</span> tel<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br></div></div><h5 id="步骤5-添加一个数据库表不存在的字段"><a href="#步骤5-添加一个数据库表不存在的字段" class="header-anchor">#</a> 步骤5:添加一个数据库表不存在的字段</h5> <div class="language-java line-numbers-mode"><pre class="language-java"><code><span class="token annotation punctuation">@Data</span>
<span class="token annotation punctuation">@TableName</span><span class="token punctuation">(</span><span class="token string">&quot;tbl_user&quot;</span><span class="token punctuation">)</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">User</span> <span class="token punctuation">{</span>
    <span class="token keyword">private</span> <span class="token class-name">Long</span> id<span class="token punctuation">;</span>
    <span class="token keyword">private</span> <span class="token class-name">String</span> name<span class="token punctuation">;</span>
    <span class="token annotation punctuation">@TableField</span><span class="token punctuation">(</span>value<span class="token operator">=</span><span class="token string">&quot;pwd&quot;</span><span class="token punctuation">)</span>
    <span class="token keyword">private</span> <span class="token class-name">String</span> password<span class="token punctuation">;</span>
    <span class="token keyword">private</span> <span class="token class-name">Integer</span> age<span class="token punctuation">;</span>
    <span class="token keyword">private</span> <span class="token class-name">String</span> tel<span class="token punctuation">;</span>
    <span class="token keyword">private</span> <span class="token class-name">Integer</span> online<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br></div></div><p>直接查询会报错，原因是MP默认情况下会查询模型类的所有属性对应的数据库表的列，而online不存在</p> <p><img src="https://img2023.cnblogs.com/blog/3089561/202302/3089561-20230203225118871-766177332.png" alt="1631032450558"></p> <h5 id="步骤6-使用-tablefield排除字段"><a href="#步骤6-使用-tablefield排除字段" class="header-anchor">#</a> 步骤6：使用@TableField排除字段</h5> <div class="language-java line-numbers-mode"><pre class="language-java"><code><span class="token annotation punctuation">@Data</span>
<span class="token annotation punctuation">@TableName</span><span class="token punctuation">(</span><span class="token string">&quot;tbl_user&quot;</span><span class="token punctuation">)</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">User</span> <span class="token punctuation">{</span>
    <span class="token keyword">private</span> <span class="token class-name">Long</span> id<span class="token punctuation">;</span>
    <span class="token keyword">private</span> <span class="token class-name">String</span> name<span class="token punctuation">;</span>
    <span class="token annotation punctuation">@TableField</span><span class="token punctuation">(</span>value<span class="token operator">=</span><span class="token string">&quot;pwd&quot;</span><span class="token punctuation">)</span>
    <span class="token keyword">private</span> <span class="token class-name">String</span> password<span class="token punctuation">;</span>
    <span class="token keyword">private</span> <span class="token class-name">Integer</span> age<span class="token punctuation">;</span>
    <span class="token keyword">private</span> <span class="token class-name">String</span> tel<span class="token punctuation">;</span>
    <span class="token annotation punctuation">@TableField</span><span class="token punctuation">(</span>exist<span class="token operator">=</span><span class="token boolean">false</span><span class="token punctuation">)</span>
    <span class="token keyword">private</span> <span class="token class-name">Integer</span> online<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br></div></div><h5 id="步骤7-查询时将pwd隐藏"><a href="#步骤7-查询时将pwd隐藏" class="header-anchor">#</a> 步骤7:查询时将pwd隐藏</h5> <div class="language-java line-numbers-mode"><pre class="language-java"><code><span class="token annotation punctuation">@Data</span>
<span class="token annotation punctuation">@TableName</span><span class="token punctuation">(</span><span class="token string">&quot;tbl_user&quot;</span><span class="token punctuation">)</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">User</span> <span class="token punctuation">{</span>
    <span class="token keyword">private</span> <span class="token class-name">Long</span> id<span class="token punctuation">;</span>
    <span class="token keyword">private</span> <span class="token class-name">String</span> name<span class="token punctuation">;</span>
    <span class="token annotation punctuation">@TableField</span><span class="token punctuation">(</span>value<span class="token operator">=</span><span class="token string">&quot;pwd&quot;</span><span class="token punctuation">,</span>select<span class="token operator">=</span><span class="token boolean">false</span><span class="token punctuation">)</span>
    <span class="token keyword">private</span> <span class="token class-name">String</span> password<span class="token punctuation">;</span>
    <span class="token keyword">private</span> <span class="token class-name">Integer</span> age<span class="token punctuation">;</span>
    <span class="token keyword">private</span> <span class="token class-name">String</span> tel<span class="token punctuation">;</span>
    <span class="token annotation punctuation">@TableField</span><span class="token punctuation">(</span>exist<span class="token operator">=</span><span class="token boolean">false</span><span class="token punctuation">)</span>
    <span class="token keyword">private</span> <span class="token class-name">Integer</span> online<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br></div></div><h2 id="mybatis-plus逻辑删除-delete字段"><a href="#mybatis-plus逻辑删除-delete字段" class="header-anchor">#</a> mybatis-plus逻辑删除（delete字段）</h2> <h3 id="_4-3-逻辑删除"><a href="#_4-3-逻辑删除" class="header-anchor">#</a> 4.3 逻辑删除</h3> <p>接下来要讲解是删除中比较重要的一个操作，逻辑删除，先来分析下问题:</p> <p><img src="https://img2023.cnblogs.com/blog/3089561/202302/3089561-20230203225118394-699477390.png" alt="1631246806130"></p> <ul><li><p>这是一个员工和其所签的合同表，关系是一个员工可以签多个合同，是一个一(员工)对多(合同)的表</p></li> <li><p>员工ID为1的张业绩，总共签了三个合同，如果此时他离职了，我们需要将员工表中的数据进行删除，会执行delete操作</p></li> <li><p>如果表在设计的时候有主外键关系，那么同时也得将合同表中的前三条数据也删除掉</p> <p><img src="https://img2023.cnblogs.com/blog/3089561/202302/3089561-20230203225117780-1522453029.png" alt="1631246997190"></p></li> <li><p>后期要统计所签合同的总金额，就会发现对不上，原因是已经将员工1签的合同信息删除掉了</p></li> <li><p>如果只删除员工不删除合同表数据，那么合同的员工编号对应的员工信息不存在，那么就会出现垃圾数据，就会出现无主合同，根本不知道有张业绩这个人的存在</p></li> <li><p>所以经过分析，我们不应该将表中的数据删除掉，而是需要进行保留，但是又得把离职的人和在职的人进行区分，这样就解决了上述问题，如:</p> <p><img src="https://img2023.cnblogs.com/blog/3089561/202302/3089561-20230203225117220-2084599685.png" alt="1631247188218"></p></li> <li><p>区分的方式，就是在员工表中添加一列数据<code>deleted</code>，如果为0说明在职员工，如果离职则将其改完1，（0和1所代表的含义是可以自定义的）</p></li></ul> <p>所以对于删除操作业务问题来说有:</p> <ul><li>物理删除:业务数据从数据库中丢弃，执行的是delete操作</li> <li>逻辑删除:为数据设置是否可用状态字段，删除时设置状态字段为不可用状态，数据保留在数据库中，执行的是update操作</li></ul> <p>MP中逻辑删除具体该如何实现?</p> <h4 id="步骤1-修改数据库表添加deleted列"><a href="#步骤1-修改数据库表添加deleted列" class="header-anchor">#</a> 步骤1:修改数据库表添加<code>deleted</code>列</h4> <p>字段名可以任意，内容也可以自定义，比如<code>0</code>代表正常，<code>1</code>代表删除，可以在添加列的同时设置其默认值为<code>0</code>正常。</p> <p><img src="https://img2023.cnblogs.com/blog/3089561/202302/3089561-20230203225116530-2024396987.png" alt="1631247439168"></p> <h4 id="步骤2-实体类添加属性"><a href="#步骤2-实体类添加属性" class="header-anchor">#</a> 步骤2:实体类添加属性</h4> <p>(1)添加与数据库表的列对应的一个属性名，名称可以任意，如果和数据表列名对不上，可以使用@TableField进行关系映射，如果一致，则会自动对应。</p> <p>(2)标识新增的字段为逻辑删除字段，使用<code>@TableLogic</code></p> <div class="language-java line-numbers-mode"><pre class="language-java"><code><span class="token annotation punctuation">@Data</span>
<span class="token comment">//@TableName(&quot;tbl_user&quot;) 可以不写是因为配置了全局配置</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">User</span> <span class="token punctuation">{</span>
    <span class="token annotation punctuation">@TableId</span><span class="token punctuation">(</span>type <span class="token operator">=</span> <span class="token class-name">IdType</span><span class="token punctuation">.</span><span class="token constant">ASSIGN_UUID</span><span class="token punctuation">)</span>
    <span class="token keyword">private</span> <span class="token class-name">String</span> id<span class="token punctuation">;</span>
    <span class="token keyword">private</span> <span class="token class-name">String</span> name<span class="token punctuation">;</span>
    <span class="token annotation punctuation">@TableField</span><span class="token punctuation">(</span>value<span class="token operator">=</span><span class="token string">&quot;pwd&quot;</span><span class="token punctuation">,</span>select<span class="token operator">=</span><span class="token boolean">false</span><span class="token punctuation">)</span>
    <span class="token keyword">private</span> <span class="token class-name">String</span> password<span class="token punctuation">;</span>
    <span class="token keyword">private</span> <span class="token class-name">Integer</span> age<span class="token punctuation">;</span>
    <span class="token keyword">private</span> <span class="token class-name">String</span> tel<span class="token punctuation">;</span>
    <span class="token annotation punctuation">@TableField</span><span class="token punctuation">(</span>exist<span class="token operator">=</span><span class="token boolean">false</span><span class="token punctuation">)</span>
    <span class="token keyword">private</span> <span class="token class-name">Integer</span> online<span class="token punctuation">;</span>
    <span class="token annotation punctuation">@TableLogic</span><span class="token punctuation">(</span>value<span class="token operator">=</span><span class="token string">&quot;0&quot;</span><span class="token punctuation">,</span>delval<span class="token operator">=</span><span class="token string">&quot;1&quot;</span><span class="token punctuation">)</span>
    <span class="token comment">//value为正常数据的值，delval为删除数据的值</span>
    <span class="token keyword">private</span> <span class="token class-name">Integer</span> deleted<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br></div></div><h4 id="步骤3-运行删除方法"><a href="#步骤3-运行删除方法" class="header-anchor">#</a> 步骤3:运行删除方法</h4> <div class="language-java line-numbers-mode"><pre class="language-java"><code><span class="token annotation punctuation">@SpringBootTest</span>
<span class="token keyword">class</span> <span class="token class-name">Mybatisplus03DqlApplicationTests</span> <span class="token punctuation">{</span>

    <span class="token annotation punctuation">@Autowired</span>
    <span class="token keyword">private</span> <span class="token class-name">UserDao</span> userDao<span class="token punctuation">;</span>
	
    <span class="token annotation punctuation">@Test</span>
    <span class="token keyword">void</span> <span class="token function">testDelete</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
       userDao<span class="token punctuation">.</span><span class="token function">deleteById</span><span class="token punctuation">(</span><span class="token number">1L</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br></div></div><p><img src="https://img2023.cnblogs.com/blog/3089561/202302/3089561-20230203225116049-1098954967.png" alt="1631247818327"></p> <p>从测试结果来看，逻辑删除最后走的是update操作，会将指定的字段修改成删除状态对应的值。</p> <p><strong>思考</strong></p> <p>逻辑删除，对查询有没有影响呢?</p> <ul><li><p>执行查询操作</p> <div class="language-java line-numbers-mode"><pre class="language-java"><code><span class="token annotation punctuation">@SpringBootTest</span>
<span class="token keyword">class</span> <span class="token class-name">Mybatisplus03DqlApplicationTests</span> <span class="token punctuation">{</span>

    <span class="token annotation punctuation">@Autowired</span>
    <span class="token keyword">private</span> <span class="token class-name">UserDao</span> userDao<span class="token punctuation">;</span>
	
    <span class="token annotation punctuation">@Test</span>
    <span class="token keyword">void</span> <span class="token function">testFind</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
       <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span>userDao<span class="token punctuation">.</span><span class="token function">selectList</span><span class="token punctuation">(</span><span class="token keyword">null</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br></div></div><p>运行测试，会发现打印出来的sql语句中会多一个查询条件，如:</p> <p><img src="https://img2023.cnblogs.com/blog/3089561/202302/3089561-20230203225115178-57178522.png" alt="1631248019999"></p> <p>可想而知，MP的逻辑删除会将所有的查询都添加一个未被删除的条件，也就是已经被删除的数据是不应该被查询出来的。</p></li> <li><p>如果还是想把已经删除的数据都查询出来该如何实现呢?</p> <div class="language-java line-numbers-mode"><pre class="language-java"><code><span class="token annotation punctuation">@Mapper</span>
<span class="token keyword">public</span> <span class="token keyword">interface</span> <span class="token class-name">UserDao</span> <span class="token keyword">extends</span> <span class="token class-name">BaseMapper</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">User</span><span class="token punctuation">&gt;</span></span> <span class="token punctuation">{</span>
    <span class="token comment">//查询所有数据包含已经被删除的数据</span>
    <span class="token annotation punctuation">@Select</span><span class="token punctuation">(</span><span class="token string">&quot;select * from tbl_user&quot;</span><span class="token punctuation">)</span>
    <span class="token keyword">public</span> <span class="token class-name">List</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">User</span><span class="token punctuation">&gt;</span></span> <span class="token function">selectAll</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br></div></div></li> <li><p>如果每个表都要有逻辑删除，那么就需要在每个模型类的属性上添加<code>@TableLogic</code>注解，如何优化?</p> <p>在配置文件中添加全局配置，如下:</p> <div class="language-yml line-numbers-mode"><pre class="language-yml"><code><span class="token key atrule">mybatis-plus</span><span class="token punctuation">:</span>
  <span class="token key atrule">global-config</span><span class="token punctuation">:</span>
    <span class="token key atrule">db-config</span><span class="token punctuation">:</span>
      <span class="token comment"># 逻辑删除字段名</span>
      <span class="token key atrule">logic-delete-field</span><span class="token punctuation">:</span> deleted
      <span class="token comment"># 逻辑删除字面值：未删除为0</span>
      <span class="token key atrule">logic-not-delete-value</span><span class="token punctuation">:</span> <span class="token number">0</span>
      <span class="token comment"># 逻辑删除字面值：删除为1</span>
      <span class="token key atrule">logic-delete-value</span><span class="token punctuation">:</span> <span class="token number">1</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br></div></div></li></ul> <p>介绍完逻辑删除，逻辑删除的本质为:</p> <p><strong>逻辑删除的本质其实是修改操作。如果加了逻辑删除字段，查询数据时也会自动带上逻辑删除字段。</strong></p> <p>执行的SQL语句为:</p> <p>UPDATE tbl_user SET ==deleted===1 where id = ? AND ==deleted===0</p> <p>执行数据结果为:</p> <p><img src="https://img2023.cnblogs.com/blog/3089561/202302/3089561-20230203225114419-24158071.png" alt="1631248494929"></p> <h4 id="知识点1-tablelogic"><a href="#知识点1-tablelogic" class="header-anchor">#</a> 知识点1：@TableLogic</h4> <table><thead><tr><th>名称</th> <th>@TableLogic</th></tr></thead> <tbody><tr><td>类型</td> <td>==属性注解==</td></tr> <tr><td>位置</td> <td>模型类中用于表示删除字段的属性定义上方</td></tr> <tr><td>作用</td> <td>标识该字段为进行逻辑删除的字段</td></tr> <tr><td>相关属性</td> <td>value：逻辑未删除值<br>delval:逻辑删除值</td></tr></tbody></table></div></div>  <div class="page-edit"><div class="edit-link"><a href="https://github.com/linxin1123/vuepress-blog/edit/master/docs/02.后端/44.SSM笔记/01.SSM复习-cnblog.md" target="_blank" rel="noopener noreferrer">编辑</a> <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></div> <!----> <div class="last-updated"><span class="prefix">上次更新:</span> <span class="time">2023/02/17, 11:29:32</span></div></div> <div class="page-nav-wapper"><div class="page-nav-centre-wrap"><a href="/pages/774997/" class="page-nav-centre page-nav-centre-prev"><div class="tooltip">MySql学习第三天</div></a> <!----></div> <div class="page-nav"><p class="inner"><span class="prev">
        ←
        <a href="/pages/774997/" class="prev">MySql学习第三天</a></span> <!----></p></div></div></div> <div class="article-list"><div class="article-title"><a href="/archives/" class="iconfont icon-bi">最近更新</a></div> <div class="article-wrapper"><dl><dd>01</dd> <dt><a href="/pages/0b785d/"><div>
            Vuex
            <!----></div></a> <span class="date">03-14</span></dt></dl><dl><dd>02</dd> <dt><a href="/pages/c59cc0/"><div>
            Vue响应式原理
            <!----></div></a> <span class="date">03-14</span></dt></dl><dl><dd>03</dd> <dt><a href="/pages/83cc7a/"><div>
            Vue虚拟DOM-cnblog
            <!----></div></a> <span class="date">03-14</span></dt></dl> <dl><dd></dd> <dt><a href="/archives/" class="more">更多文章&gt;</a></dt></dl></div></div></main></div> <div class="footer"><div class="icons"><a href="3010733382@qq.com" title="发邮件" target="_blank" class="iconfont icon-youjian"></a><a href="https://github.com/linxin1123" title="GitHub" target="_blank" class="iconfont icon-github"></a><a href="https://music.163.com/#/playlist?id=755597173" title="听音乐" target="_blank" class="iconfont icon-erji"></a></div> 
  Theme by
  <a href="https://github.com/xugaoyi/vuepress-theme-vdoing" target="_blank" title="本站主题">Vdoing</a> 
    | Copyright © 2022-2023
    <span>lingxin | <a href="https://github.com/linxin1123/vuepress-blog/blob/master/LICENSE" target="_blank">MIT License</a></span></div> <div class="buttons"><div title="返回顶部" class="button blur go-to-top iconfont icon-fanhuidingbu" style="display:none;"></div> <div title="去评论" class="button blur go-to-comment iconfont icon-pinglun" style="display:none;"></div> <div title="主题模式" class="button blur theme-mode-but iconfont icon-zhuti"><ul class="select-box" style="display:none;"><li class="iconfont icon-zidong">
          跟随系统
        </li><li class="iconfont icon-rijianmoshi">
          浅色模式
        </li><li class="iconfont icon-yejianmoshi">
          深色模式
        </li><li class="iconfont icon-yuedu">
          阅读模式
        </li></ul></div></div> <!----> <!----> <!----></div><div class="global-ui"><div></div></div></div>
    <script src="/assets/js/app.57550e13.js" defer></script><script src="/assets/js/2.f014c35f.js" defer></script><script src="/assets/js/94.b6bc4a44.js" defer></script>
  </body>
</html>
